You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
depot_tools/metadata/fields/custom/mitigated.py

86 lines
2.7 KiB
Python

#!/usr/bin/env python3
# Copyright 2025 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
from typing import List, Optional, Tuple
import metadata.fields.field_types as field_types
import metadata.fields.util as util
import metadata.validation_result as vr
# List of supported vulnerability ID prefixes.
_VULN_PREFIXES = [
"CVE", # Common Vulnerabilities and Exposures.
"GHSA", # GitHub Security Advisory.
"PYSEC", # Python Security Advisory.
"OSV", # Open Source Vulnerability.
"DSA", # Debian Security Advisory.
]
_PREFIX_PATTERN = "|".join(_VULN_PREFIXES)
_VULN_ID_PATTERN = re.compile(
rf"^({_PREFIX_PATTERN})-[a-zA-Z0-9]{{4}}-[a-zA-Z0-9:-]+$")
def validate_vuln_ids(vuln_ids: str) -> Tuple[List[str], List[str]]:
"""
Validates a list of vulnerability identifiers and returns valid and invalid IDs.
Supports multiple formats:
- CVE IDs (e.g., CVE-2024-12345)
- GitHub Security Advisories (e.g., GHSA-1234-5678-90ab)
- Python Security Advisories (e.g., PYSEC-2024-1234)
- Open Source Vulnerabilities (e.g., OSV-2024-1234)
- Debian Security Advisories (e.g., DSA-1234-1)
Args:
vuln_ids: List of vulnerability identifiers to validate
Returns:
Tuple of (valid_ids, invalid_ids)
"""
valid_vuln_ids = []
invalid_vuln_ids = []
for cve in vuln_ids.split(","):
cve_stripped = cve.strip()
if _VULN_ID_PATTERN.match(cve_stripped):
valid_vuln_ids.append(cve_stripped)
else:
invalid_vuln_ids.append(cve)
return valid_vuln_ids, invalid_vuln_ids
class MitigatedField(field_types.SingleLineTextField):
"""Field for comma-separated vulnerability IDs."""
def __init__(self):
super().__init__(name="Mitigated")
def validate(self, value: str) -> Optional[vr.ValidationResult]:
"""Checks if the value contains valid CVE IDs."""
if util.is_empty(value):
return None
_, invalid_vuln_ids = validate_vuln_ids(value)
if invalid_vuln_ids:
return vr.ValidationWarning(
reason=f"{self._name} contains invalid vulnerability IDs.",
additional=[
f"Invalid Vulnerability IDs: {util.quoted(invalid_vuln_ids)}",
"The following identifiers are supported: " +
", ".join(_VULN_PREFIXES),
],
)
return None
def narrow_type(self, value: str) -> Optional[List[str]]:
if not value:
return None
vuln_ids, _ = validate_vuln_ids(value)
return vuln_ids