from __future__ import annotations

import re
from dataclasses import dataclass, field
from functools import lru_cache
from typing import Any

from dsc.scanner.models import Severity


@dataclass(frozen=True, slots=True)
class VulnerabilityDefinition:
    id: str
    cwe: str
    name: str
    description: str
    severity_default: Severity
    tags: tuple[str, ...] = ()
    languages: tuple[str, ...] = ()
    vulnerable_example: str | None = None
    secure_example: str | None = None
    fix_suggestion: str | None = None
    references: tuple[str, ...] = ()
    detection_hints: dict[str, Any] = field(default_factory=dict)

    @property
    def has_detection_patterns(self) -> bool:
        """True if this rule has detection data that can generate a detector."""
        return bool(
            self.detection_hints.get("regex_patterns")
            or self.detection_hints.get("taint_sinks")
        )


_BASE_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "CWE-208": VulnerabilityDefinition(
        id="CWE-208",
        cwe="CWE-208",
        name="Timing Attack (secret comparison)",
        description=(
            "Detects secret comparisons using ==/!= which may leak timing information. "
            "Prefer constant-time comparisons like hmac.compare_digest()."
        ),
        severity_default=Severity.HIGH,
        tags=("susvibes", "owasp-top10-2025-a07", "owasp-mobile-top10-2024-m3"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example="if password == stored_password:\n    ...",
        secure_example="if hmac.compare_digest(password, stored_password):\n    ...",
        fix_suggestion="Use hmac.compare_digest(a, b) instead of ==/!= for secret comparisons.",
        references=("CWE-208: Observable Timing Discrepancy",),
    ),
    "CWE-327": VulnerabilityDefinition(
        id="CWE-327",
        cwe="CWE-327",
        name="Broken or Risky Cryptography",
        description=(
            "Detects use of weak/obsolete cryptographic primitives such as MD5, SHA1, DES, "
            "RC4, or ECB mode."
        ),
        severity_default=Severity.HIGH,
        tags=("crypto", "owasp-top10-2025-a04", "owasp-mobile-top10-2024-m10"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='hashlib.md5(password.encode("utf-8")).hexdigest()\n',
        secure_example='hashlib.sha256(password.encode("utf-8")).hexdigest()\n',
        fix_suggestion=(
            "Use modern cryptography (e.g., SHA-256+, AES-GCM, Argon2/bcrypt/scrypt for passwords) "
            "and avoid obsolete algorithms."
        ),
        references=("CWE-327: Use of a Broken or Risky Cryptographic Algorithm",),
    ),
    "CWE-521": VulnerabilityDefinition(
        id="CWE-521",
        cwe="CWE-521",
        name="Weak Password Requirements",
        description=(
            "Detects password validation logic that does not enforce a minimum length of 8+ "
            "and common default passwords in configuration."
        ),
        severity_default=Severity.CRITICAL,
        tags=("openclaw", "owasp-top10-2025-a07", "owasp-mobile-top10-2024-m1", "owasp-mobile-top10-2024-m3"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example="def validate_password(p):\n    return bool(p)  # accepts 'a'\n",
        secure_example="def validate_password(p):\n    return len(p) >= 12\n",
        fix_suggestion="Enforce a minimum password length (>= 8) and disallow default passwords.",
        references=("CWE-521: Weak Password Requirements",),
    ),
    "CWE-532": VulnerabilityDefinition(
        id="CWE-532",
        cwe="CWE-532",
        name="PHI in Logs",
        description=(
            "Detects potential Protected Health Information (PHI) being logged in application "
            "logs, console output, or error messages."
        ),
        severity_default=Severity.HIGH,
        tags=("healthcare", "hipaa", "compliance", "owasp-top10-2025-a09", "owasp-mobile-top10-2024-m6"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='logger.info(f"patient ssn={ssn}")\n',
        secure_example='logger.info("patient_id=%s", patient_id)\n',
        fix_suggestion="Avoid logging PHI/PII; log non-sensitive identifiers and redact where needed.",
        references=("CWE-532: Insertion of Sensitive Information into Log File",),
    ),
    "CWE-639": VulnerabilityDefinition(
        id="CWE-639",
        cwe="CWE-639",
        name="IDOR (Missing Ownership Check)",
        description=(
            "Heuristically detects Insecure Direct Object Reference (IDOR) patterns where a "
            "resource is fetched by an ID from a request without an obvious ownership/authorization check."
        ),
        severity_default=Severity.HIGH,
        tags=("susvibes", "owasp-top10-2025-a01", "owasp-mobile-top10-2024-m3"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example="patient = Patient.objects.get(id=patient_id)\n",
        secure_example="patient = Patient.objects.get(id=patient_id, owner_id=current_user.id)\n",
        fix_suggestion=(
            "Ensure authorization/ownership is enforced (e.g., filter by current user/tenant or add a dedicated auth check)."
        ),
        references=("CWE-639: Authorization Bypass Through User-Controlled Key",),
    ),
    "CWE-78": VulnerabilityDefinition(
        id="CWE-78",
        cwe="CWE-78",
        name="OS Command Injection",
        description=(
            "Detects command execution sinks where untrusted input may reach shell/system calls."
        ),
        severity_default=Severity.CRITICAL,
        tags=("injection", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='os.system("grep " + user_input)\n',
        secure_example='subprocess.run(["grep", safe_value], check=True)\n',
        fix_suggestion=(
            "Avoid shell command construction from user input. Prefer safe APIs that pass arguments "
            "as arrays and validate/allowlist inputs."
        ),
        references=("CWE-78: Improper Neutralization of Special Elements used in an OS Command",),
    ),
    "CWE-79": VulnerabilityDefinition(
        id="CWE-79",
        cwe="CWE-79",
        name="Cross-Site Scripting (XSS)",
        description=(
            "Detects potentially unsafe insertion of untrusted input into HTML rendering sinks."
        ),
        severity_default=Severity.HIGH,
        tags=("injection", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='element.innerHTML = req.query.q\n',
        secure_example='element.textContent = sanitize(req.query.q)\n',
        fix_suggestion=(
            "Encode or sanitize untrusted content before rendering. Prefer safe DOM APIs "
            "(e.g., textContent) and vetted sanitizers."
        ),
        references=("CWE-79: Improper Neutralization of Input During Web Page Generation",),
    ),
    "CWE-89": VulnerabilityDefinition(
        id="CWE-89",
        cwe="CWE-89",
        name="SQL Injection",
        description=(
            "Detects dynamic SQL string construction with untrusted input flowing into query execution."
        ),
        severity_default=Severity.CRITICAL,
        tags=("injection", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='cursor.execute("SELECT * FROM users WHERE id=" + user_id)\n',
        secure_example='cursor.execute("SELECT * FROM users WHERE id=%s", (user_id,))\n',
        fix_suggestion=(
            "Use parameterized queries/prepared statements and never concatenate untrusted input into SQL."
        ),
        references=("CWE-89: Improper Neutralization of Special Elements used in an SQL Command",),
    ),
    "CWE-502": VulnerabilityDefinition(
        id="CWE-502",
        cwe="CWE-502",
        name="Insecure Deserialization",
        description=(
            "Detects potentially unsafe deserialization APIs used with untrusted input."
        ),
        severity_default=Severity.HIGH,
        tags=("integrity", "owasp-top10-2025-a08", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example="obj = pickle.loads(request.data)\n",
        secure_example="obj = json.loads(request.data)\n",
        fix_suggestion=(
            "Avoid unsafe object deserialization for untrusted input. Use safer formats "
            "(JSON) and strict validation."
        ),
        references=("CWE-502: Deserialization of Untrusted Data",),
    ),
    "CWE-669": VulnerabilityDefinition(
        id="CWE-669",
        cwe="CWE-669",
        name="Exposed Service / Insecure Deployment Defaults",
        description=(
            "Detects patterns that may expose a service publicly (e.g., binding to 0.0.0.0) "
            "and common insecure deployment flags or default credentials."
        ),
        severity_default=Severity.CRITICAL,
        tags=("openclaw", "deployment", "owasp-top10-2025-a02", "owasp-mobile-top10-2024-m5", "owasp-mobile-top10-2024-m8"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example="app.run(host='0.0.0.0', port=8000)\n",
        secure_example="app.run(host='127.0.0.1', port=8000)\n",
        fix_suggestion=(
            "Bind to localhost by default and require explicit configuration for public exposure; "
            "never ship default credentials and avoid disabling TLS/auth checks."
        ),
        references=("CWE-669: Incorrect Resource Transfer Between Spheres",),
    ),
    "CWE-798": VulnerabilityDefinition(
        id="CWE-798",
        cwe="CWE-798",
        name="Hardcoded API Keys / Credentials",
        description=(
            "Detects hardcoded secrets in source code, including API keys, provider tokens, "
            "and private key material that may be accidentally committed to repositories."
        ),
        severity_default=Severity.CRITICAL,
        tags=("credentials", "secrets", "owasp-top10-2025-a07", "owasp-mobile-top10-2024-m1", "owasp-mobile-top10-2024-m9"),
        languages=("python", "javascript", "typescript", "json", "yaml", "ini", "toml", "terraform", "ruby", "go", "java", "php", "csharp"),
        vulnerable_example='OPENAI_API_KEY = "sk-proj-..."\n',
        secure_example='OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")\n',
        fix_suggestion=(
            "Remove embedded secrets from source control, rotate exposed keys immediately, "
            "and load credentials from environment variables or a secrets manager."
        ),
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
    "CWE-918": VulnerabilityDefinition(
        id="CWE-918",
        cwe="CWE-918",
        name="Server-Side Request Forgery (SSRF)",
        description=(
            "Detects outbound HTTP requests that appear to use user-controlled URLs."
        ),
        severity_default=Severity.HIGH,
        tags=("ssrf", "owasp-top10-2025-a10", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='requests.get(request.args["url"])\n',
        secure_example='requests.get(allowlisted_url)\n',
        fix_suggestion=(
            "Validate and allowlist destination URLs/hosts, block internal address ranges, "
            "and avoid direct proxying of user-provided URLs."
        ),
        references=("CWE-918: Server-Side Request Forgery (SSRF)",),
    ),
    "CWE-943": VulnerabilityDefinition(
        id="CWE-943",
        cwe="CWE-943",
        name="NoSQL Injection",
        description=(
            "Detects NoSQL query construction where untrusted input may manipulate query operators "
            "or filter objects (e.g., MongoDB $where, $ne, $gt, $regex)."
        ),
        severity_default=Severity.CRITICAL,
        tags=("injection", "nosql", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='db.users.find({"username": req.body.username})\n',
        secure_example='db.users.find({"username": sanitize(req.body.username)})\n',
        fix_suggestion=(
            "Never pass raw request objects as query filters. Validate and sanitize all inputs, "
            "use schema validation, and block operator injection ($ne, $gt, $regex, $where)."
        ),
        references=("CWE-943: Improper Neutralization of Special Elements in Data Query Logic",),
    ),
    "CWE-1336": VulnerabilityDefinition(
        id="CWE-1336",
        cwe="CWE-1336",
        name="Server-Side Template Injection (SSTI)",
        description=(
            "Detects template rendering where user input is used as the template string itself, "
            "enabling arbitrary code execution via template engines."
        ),
        severity_default=Severity.CRITICAL,
        tags=("injection", "ssti", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
        languages=("python", "javascript", "typescript", "java", "go"),
        vulnerable_example='render_template_string(request.args["template"])\n',
        secure_example='render_template("page.html", data=request.args["data"])\n',
        fix_suggestion=(
            "Never use user input as a template string. Render pre-defined template files with "
            "user data passed as context variables, and enable auto-escaping/sandbox modes."
        ),
        references=("CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine",),
    ),
    "CWE-1321": VulnerabilityDefinition(
        id="CWE-1321",
        cwe="CWE-1321",
        name="Prototype Pollution",
        description=(
            "Detects JavaScript prototype chain manipulation via __proto__, constructor.prototype, "
            "or unsafe deep-merge operations with attacker-controlled input."
        ),
        severity_default=Severity.HIGH,
        tags=("prototype-pollution", "owasp-top10-2025-a05"),
        languages=("javascript", "typescript"),
        vulnerable_example='Object.assign(target, JSON.parse(userInput))\n',
        secure_example='Object.assign(Object.create(null), validated)\n',
        fix_suggestion=(
            "Block __proto__, constructor, and prototype keys in merge/assignment operations. "
            "Use Object.create(null) for lookup maps and validate input schemas."
        ),
        references=("CWE-1321: Improperly Controlled Modification of Object Prototype Attributes",),
    ),
    "CWE-90": VulnerabilityDefinition(
        id="CWE-90",
        cwe="CWE-90",
        name="LDAP Injection",
        description=(
            "Detects LDAP filter/query construction with unsanitized user input that may allow "
            "filter manipulation or authentication bypass."
        ),
        severity_default=Severity.HIGH,
        tags=("injection", "ldap", "owasp-top10-2025-a05"),
        languages=("python", "javascript", "typescript", "java"),
        vulnerable_example='ldap.search_s(dn, ldap.SCOPE_SUBTREE, f"(uid={username})")\n',
        secure_example='ldap.search_s(dn, ldap.SCOPE_SUBTREE, "(uid=%s)" % escape_filter_chars(username))\n',
        fix_suggestion=(
            "Use LDAP escaping functions (e.g., ldap.filter.escape_filter_chars) for all "
            "user-supplied values in LDAP filters. Never concatenate raw input into filter strings."
        ),
        references=("CWE-90: Improper Neutralization of Special Elements used in an LDAP Query",),
    ),
}


_DEFAULT_LANGUAGES = (
    "python", "javascript", "typescript", "go", "java", "ruby", "rust",
    "swift", "objc", "kotlin", "php", "csharp", "dart", "c", "cpp",
)
_CONFIG_LANGUAGES = (
    "json",
    "yaml",
    "toml",
    "ini",
    "xml",
    "html",
    "css",
    "markdown",
    "text",
    "dockerfile",
    "dockercompose",
    "terraform",
    "requirements",
    "lockfile",
    "gomod",
    "gradle",
    "runtime",
    "plist",
)
_ALL_SCANNER_LANGUAGES = tuple(dict.fromkeys((*_DEFAULT_LANGUAGES, *_CONFIG_LANGUAGES)))


def _extended_vulnerability_definitions() -> dict[str, VulnerabilityDefinition]:
    # Centralized, in-repo rule metadata for broader static coverage.
    return {
        "CWE-22": VulnerabilityDefinition(
            id="CWE-22",
            cwe="CWE-22",
            name="Path Traversal",
            description="Detects file path handling that may allow directory traversal using user input.",
            severity_default=Severity.CRITICAL,
            tags=("injection", "filesystem", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion=(
                "Normalize and validate file paths, enforce root allowlists, and reject traversal tokens "
                "such as ../ and ..\\."
            ),
            references=("CWE-22: Improper Limitation of a Pathname to a Restricted Directory",),
        ),
        "CWE-73": VulnerabilityDefinition(
            id="CWE-73",
            cwe="CWE-73",
            name="External Control of File Name or Path",
            description="Detects externally-controlled file names or paths flowing into file system operations.",
            severity_default=Severity.HIGH,
            tags=("filesystem", "input-validation", "owasp-top10-2025-a05"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Do not trust externally supplied file names; map to server-side identifiers/allowlists.",
            references=("CWE-73: External Control of File Name or Path",),
        ),
        "CWE-94": VulnerabilityDefinition(
            id="CWE-94",
            cwe="CWE-94",
            name="Code Injection",
            description="Detects dynamic code execution primitives fed by untrusted input.",
            severity_default=Severity.CRITICAL,
            tags=("injection", "code-exec", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Eliminate eval/exec-style execution for untrusted data; use strict parsers/allowlists.",
            references=("CWE-94: Improper Control of Generation of Code ('Code Injection')",),
        ),
        "CWE-119": VulnerabilityDefinition(
            id="CWE-119",
            cwe="CWE-119",
            name="Memory Buffer Bounds Violation",
            description="Detects unsafe memory-manipulation patterns associated with buffer overflows/corruption.",
            severity_default=Severity.CRITICAL,
            tags=("memory-safety", "owasp-top10-2025-a08"),
            languages=("rust", "go", "java"),
            fix_suggestion=(
                "Use memory-safe APIs and enforce strict bounds checks; avoid unsafe pointer operations "
                "without explicit validation."
            ),
            references=("CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer",),
        ),
        "CWE-200": VulnerabilityDefinition(
            id="CWE-200",
            cwe="CWE-200",
            name="Information Exposure",
            description="Detects potential disclosure of sensitive information in logs, responses, or debugging output.",
            severity_default=Severity.HIGH,
            tags=("privacy", "data-leak", "owasp-top10-2025-a09"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Redact sensitive values and minimize sensitive data in logs/responses.",
            references=("CWE-200: Exposure of Sensitive Information to an Unauthorized Actor",),
        ),
        "CWE-259": VulnerabilityDefinition(
            id="CWE-259",
            cwe="CWE-259",
            name="Hard-coded Password",
            description="Detects hard-coded password literals in application code.",
            severity_default=Severity.CRITICAL,
            tags=("credentials", "secrets", "owasp-top10-2025-a07", "owasp-mobile-top10-2024-m1"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Move credentials to a secrets manager or environment variables and rotate exposed values.",
            references=("CWE-259: Use of Hard-coded Password",),
        ),
        "CWE-284": VulnerabilityDefinition(
            id="CWE-284",
            cwe="CWE-284",
            name="Improper Access Control",
            description="Detects patterns that appear to broadly bypass or disable access control checks.",
            severity_default=Severity.HIGH,
            tags=("authorization", "owasp-top10-2025-a01", "owasp-mobile-top10-2024-m3"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Apply deny-by-default authorization and avoid global bypass toggles in production.",
            references=("CWE-284: Improper Access Control",),
        ),
        "CWE-285": VulnerabilityDefinition(
            id="CWE-285",
            cwe="CWE-285",
            name="Improper Authorization",
            description="Detects weak or trivially bypassable authorization checks.",
            severity_default=Severity.HIGH,
            tags=("authorization", "owasp-top10-2025-a01", "owasp-mobile-top10-2024-m3"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Enforce server-side authorization with robust policy checks independent of user input.",
            references=("CWE-285: Improper Authorization",),
        ),
        "CWE-287": VulnerabilityDefinition(
            id="CWE-287",
            cwe="CWE-287",
            name="Improper Authentication",
            description="Detects authentication logic that may always succeed or be trivially bypassed.",
            severity_default=Severity.HIGH,
            tags=("authentication", "owasp-top10-2025-a07", "owasp-mobile-top10-2024-m3"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Implement robust authentication with strict verification paths and negative test coverage.",
            references=("CWE-287: Improper Authentication",),
        ),
        "CWE-295": VulnerabilityDefinition(
            id="CWE-295",
            cwe="CWE-295",
            name="Improper Certificate Validation",
            description="Detects disabled TLS certificate validation or equivalent trust bypasses.",
            severity_default=Severity.HIGH,
            tags=("tls", "crypto", "owasp-top10-2025-a02", "owasp-mobile-top10-2024-m5"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Enable strict certificate/hostname verification and remove trust-bypass flags.",
            references=("CWE-295: Improper Certificate Validation",),
        ),
        "CWE-311": VulnerabilityDefinition(
            id="CWE-311",
            cwe="CWE-311",
            name="Missing Encryption of Sensitive Data",
            description="Detects transmission/storage patterns indicating sensitive data may lack encryption.",
            severity_default=Severity.HIGH,
            tags=("crypto", "privacy", "owasp-top10-2025-a02", "owasp-mobile-top10-2024-m10"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Use TLS in transit and strong encryption at rest for sensitive data.",
            references=("CWE-311: Missing Encryption of Sensitive Data",),
        ),
        "CWE-312": VulnerabilityDefinition(
            id="CWE-312",
            cwe="CWE-312",
            name="Cleartext Storage of Sensitive Information",
            description="Detects potential cleartext persistence of credentials/tokens/secrets.",
            severity_default=Severity.HIGH,
            tags=("privacy", "data-storage", "owasp-mobile-top10-2024-m9"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Encrypt sensitive values at rest and avoid storing long-lived secrets in plaintext.",
            references=("CWE-312: Cleartext Storage of Sensitive Information",),
        ),
        "CWE-330": VulnerabilityDefinition(
            id="CWE-330",
            cwe="CWE-330",
            name="Use of Insufficiently Random Values",
            description="Detects non-cryptographic randomness used in security-sensitive contexts.",
            severity_default=Severity.HIGH,
            tags=("crypto", "predictability", "owasp-top10-2025-a02"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Use cryptographically secure random APIs for tokens, nonces, and credentials.",
            references=("CWE-330: Use of Insufficiently Random Values",),
        ),
        "CWE-347": VulnerabilityDefinition(
            id="CWE-347",
            cwe="CWE-347",
            name="Improper Verification of Cryptographic Signature",
            description="Detects signature verification bypasses or disabled verification options.",
            severity_default=Severity.HIGH,
            tags=("crypto", "integrity", "owasp-top10-2025-a08"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Always verify signatures with trusted keys and fail closed on verification errors.",
            references=("CWE-347: Improper Verification of Cryptographic Signature",),
        ),
        "CWE-352": VulnerabilityDefinition(
            id="CWE-352",
            cwe="CWE-352",
            name="Cross-Site Request Forgery (CSRF)",
            description="Detects CSRF protection disablement or explicit exempt/bypass controls.",
            severity_default=Severity.HIGH,
            tags=("web", "csrf", "owasp-top10-2025-a01"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion=(
                "Enable CSRF protection for state-changing requests and validate anti-CSRF tokens server-side."
            ),
            references=("CWE-352: Cross-Site Request Forgery (CSRF)",),
        ),
        "CWE-384": VulnerabilityDefinition(
            id="CWE-384",
            cwe="CWE-384",
            name="Session Fixation",
            description="Detects session identifier assignment from untrusted request data.",
            severity_default=Severity.HIGH,
            tags=("session", "authentication", "owasp-top10-2025-a07"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Regenerate session IDs after authentication and never accept externally supplied IDs.",
            references=("CWE-384: Session Fixation",),
        ),
        "CWE-400": VulnerabilityDefinition(
            id="CWE-400",
            cwe="CWE-400",
            name="Uncontrolled Resource Consumption",
            description="Detects patterns suggesting unbounded loops/allocations or abuse-prone workloads.",
            severity_default=Severity.HIGH,
            tags=("availability", "dos", "owasp-top10-2025-a06"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Add strict limits, timeouts, pagination, and quotas to resource-intensive operations.",
            references=("CWE-400: Uncontrolled Resource Consumption",),
        ),
        "CWE-416": VulnerabilityDefinition(
            id="CWE-416",
            cwe="CWE-416",
            name="Use After Free",
            description="Detects suspicious patterns where memory/object handles appear reused after free/drop.",
            severity_default=Severity.CRITICAL,
            tags=("memory-safety", "owasp-top10-2025-a08"),
            languages=("rust", "go", "java"),
            fix_suggestion="Avoid using pointers/handles after free/drop; use ownership/lifetime-safe abstractions.",
            references=("CWE-416: Use After Free",),
        ),
        "CWE-434": VulnerabilityDefinition(
            id="CWE-434",
            cwe="CWE-434",
            name="Unrestricted File Upload",
            description="Detects file upload handling that may lack robust type/path/content controls.",
            severity_default=Severity.HIGH,
            tags=("file-upload", "owasp-top10-2025-a05"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion=(
                "Validate file type and content, enforce size limits, and store uploads outside executable paths."
            ),
            references=("CWE-434: Unrestricted Upload of File with Dangerous Type",),
        ),
        "CWE-522": VulnerabilityDefinition(
            id="CWE-522",
            cwe="CWE-522",
            name="Insufficiently Protected Credentials",
            description="Detects weak protection mechanisms applied to credential material.",
            severity_default=Severity.HIGH,
            tags=("credentials", "crypto", "owasp-top10-2025-a07"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Use strong hashing/derivation and secure storage controls for credential data.",
            references=("CWE-522: Insufficiently Protected Credentials",),
        ),
        "CWE-523": VulnerabilityDefinition(
            id="CWE-523",
            cwe="CWE-523",
            name="Unprotected Transport of Credentials",
            description="Detects credential-bearing traffic that appears to use insecure transport.",
            severity_default=Severity.HIGH,
            tags=("credentials", "transport", "owasp-top10-2025-a02"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Transmit credentials only over TLS-protected channels and reject insecure endpoints.",
            references=("CWE-523: Unprotected Transport of Credentials",),
        ),
        "CWE-524": VulnerabilityDefinition(
            id="CWE-524",
            cwe="CWE-524",
            name="Use of Cache Containing Sensitive Information",
            description="Detects cache directives/usages that may expose sensitive authenticated content.",
            severity_default=Severity.MEDIUM,
            tags=("privacy", "cache", "owasp-top10-2025-a09"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Set conservative cache headers for sensitive responses (e.g., no-store/private).",
            references=("CWE-524: Use of Cache Containing Sensitive Information",),
        ),
        "CWE-540": VulnerabilityDefinition(
            id="CWE-540",
            cwe="CWE-540",
            name="Information Exposure Through Source Code",
            description="Detects debug/verbose settings that may expose sensitive implementation details.",
            severity_default=Severity.MEDIUM,
            tags=("information-disclosure", "debugging", "owasp-top10-2025-a09"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Disable debug/stacktrace verbosity in production and sanitize diagnostic output.",
            references=("CWE-540: Inclusion of Sensitive Information in Source Code",),
        ),
        "CWE-601": VulnerabilityDefinition(
            id="CWE-601",
            cwe="CWE-601",
            name="Open Redirect",
            description="Detects redirects that may use user-controlled destinations without validation.",
            severity_default=Severity.HIGH,
            tags=("redirect", "owasp-top10-2025-a01"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Allowlist redirect destinations and avoid direct redirection from user input.",
            references=("CWE-601: URL Redirection to Untrusted Site ('Open Redirect')",),
        ),
        "CWE-611": VulnerabilityDefinition(
            id="CWE-611",
            cwe="CWE-611",
            name="XXE Injection",
            description="Detects XML parsing configurations that may allow external entity expansion.",
            severity_default=Severity.HIGH,
            tags=("xxe", "parser", "owasp-top10-2025-a05", "owasp-mobile-top10-2024-m4"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Disable external entities/DTDs and use hardened XML parser settings.",
            references=("CWE-611: Improper Restriction of XML External Entity Reference",),
        ),
        "CWE-614": VulnerabilityDefinition(
            id="CWE-614",
            cwe="CWE-614",
            name="Sensitive Cookie Without Secure Attribute",
            description="Detects cookie handling patterns indicating missing Secure transport protection.",
            severity_default=Severity.MEDIUM,
            tags=("web", "cookie", "transport", "owasp-top10-2025-a02"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Set Secure and HttpOnly attributes for sensitive cookies and enforce HTTPS.",
            references=("CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute",),
        ),
        "CWE-732": VulnerabilityDefinition(
            id="CWE-732",
            cwe="CWE-732",
            name="Incorrect Permission Assignment for Critical Resource",
            description="Detects overly permissive file/resource permission settings.",
            severity_default=Severity.HIGH,
            tags=("permissions", "filesystem", "owasp-top10-2025-a05"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Apply least-privilege permissions (avoid world-writable/readable defaults).",
            references=("CWE-732: Incorrect Permission Assignment for Critical Resource",),
        ),
        "CWE-862": VulnerabilityDefinition(
            id="CWE-862",
            cwe="CWE-862",
            name="Missing Authorization",
            description="Detects explicit code paths/routes that bypass authorization requirements.",
            severity_default=Severity.HIGH,
            tags=("authorization", "owasp-top10-2025-a01", "owasp-mobile-top10-2024-m3"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Require authorization checks on every protected operation and fail closed by default.",
            references=("CWE-862: Missing Authorization",),
        ),
        "CWE-863": VulnerabilityDefinition(
            id="CWE-863",
            cwe="CWE-863",
            name="Incorrect Authorization",
            description="Detects authorization conditions likely to be bypassable or incorrectly implemented.",
            severity_default=Severity.HIGH,
            tags=("authorization", "owasp-top10-2025-a01", "owasp-mobile-top10-2024-m3"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Implement centralized policy enforcement and remove permissive fallback branches.",
            references=("CWE-863: Incorrect Authorization",),
        ),
        "CWE-915": VulnerabilityDefinition(
            id="CWE-915",
            cwe="CWE-915",
            name="Prototype Pollution / Object Attribute Tampering",
            description="Detects writes to dynamic object prototype chains and unsafe deep-merge behavior.",
            severity_default=Severity.HIGH,
            tags=("prototype-pollution", "input-validation", "owasp-top10-2025-a05"),
            languages=("javascript", "typescript"),
            fix_suggestion=(
                "Block __proto__/constructor/prototype keys and use safe merge routines with strict schemas."
            ),
            references=("CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes",),
        ),
        "CWE-922": VulnerabilityDefinition(
            id="CWE-922",
            cwe="CWE-922",
            name="Insecure Storage of Sensitive Information",
            description="Detects potentially sensitive values persisted in client/local storage without protection.",
            severity_default=Severity.HIGH,
            tags=("privacy", "mobile", "owasp-mobile-top10-2024-m9"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Avoid persistent plaintext storage for sensitive data; encrypt and minimize retention.",
            references=("CWE-922: Insecure Storage of Sensitive Information",),
        ),
        "CWE-1333": VulnerabilityDefinition(
            id="CWE-1333",
            cwe="CWE-1333",
            name="Inefficient Regular Expression Complexity (ReDoS)",
            description="Detects suspicious catastrophic-backtracking regex patterns.",
            severity_default=Severity.MEDIUM,
            tags=("regex", "dos", "owasp-top10-2025-a06"),
            languages=_DEFAULT_LANGUAGES,
            fix_suggestion="Use linear-time regexes, length limits, and timeouts for untrusted input matching.",
            references=("CWE-1333: Inefficient Regular Expression Complexity",),
        ),
        "CWE-693": VulnerabilityDefinition(
            id="CWE-693",
            cwe="CWE-693",
            name="Protection Mechanism Failure",
            description=(
                "Detects missing or disabled browser security headers such as Content-Security-Policy "
                "and HTTP Strict Transport Security (HSTS)."
            ),
            severity_default=Severity.MEDIUM,
            tags=("web", "headers", "misconfiguration", "owasp-top10-2025-a02"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion=(
                "Enable Content-Security-Policy with restrictive directives and set HSTS with a "
                "reasonable max-age (e.g., 31536000)."
            ),
            references=("CWE-693: Protection Mechanism Failure",),
        ),
        "CWE-444": VulnerabilityDefinition(
            id="CWE-444",
            cwe="CWE-444",
            name="HTTP Request Smuggling",
            description=(
                "Detects conflicting Transfer-Encoding and Content-Length headers or patterns "
                "that enable HTTP request smuggling attacks."
            ),
            severity_default=Severity.HIGH,
            tags=("web", "http", "owasp-top10-2025-a05"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion=(
                "Use HTTP/2 where possible, reject ambiguous requests with conflicting "
                "Transfer-Encoding and Content-Length headers, and normalize request parsing."
            ),
            references=("CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request Smuggling')",),
        ),
    }


_EXTENDED_VULNERABILITIES = _extended_vulnerability_definitions()


def _policy_and_supply_chain_definitions() -> dict[str, VulnerabilityDefinition]:
    # Coverage for policy/compliance baselines, auth/access hardening, and dependency risk.
    return {
        "CWE-16": VulnerabilityDefinition(
            id="CWE-16",
            cwe="CWE-16",
            name="Security Misconfiguration",
            description=(
                "Detects insecure configuration defaults across application, infrastructure, and "
                "deployment artifacts."
            ),
            severity_default=Severity.HIGH,
            tags=(
                "misconfiguration",
                "cis",
                "nist-800-53",
                "pci-dss",
                "hipaa",
                "iso-27001",
                "owasp-top10-2025-a02",
            ),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Harden defaults, disable insecure debug modes, and enforce secure baseline settings.",
            references=("CWE-16: Configuration",),
        ),
        "CWE-113": VulnerabilityDefinition(
            id="CWE-113",
            cwe="CWE-113",
            name="HTTP Response Splitting (CRLF Injection)",
            description=(
                "Detects header/redirect handling that may allow CRLF-based header injection."
            ),
            severity_default=Severity.HIGH,
            tags=("web", "injection", "susvibes", "owasp-top10-2025-a05"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion=(
                "Normalize and validate header values and reject CR/LF characters in user-controlled fields."
            ),
            references=("CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers",),
        ),
        "CWE-250": VulnerabilityDefinition(
            id="CWE-250",
            cwe="CWE-250",
            name="Execution with Unnecessary Privileges",
            description="Detects patterns that run services/containers/operations with unnecessary high privileges.",
            severity_default=Severity.HIGH,
            tags=("privilege", "least-privilege", "cloud", "cis", "nist-800-53", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Run with least privilege, drop root/admin defaults, and scope permissions narrowly.",
            references=("CWE-250: Execution with Unnecessary Privileges",),
        ),
        "CWE-266": VulnerabilityDefinition(
            id="CWE-266",
            cwe="CWE-266",
            name="Incorrect Privilege Assignment",
            description="Detects broad/wildcard privilege assignments and role over-granting patterns.",
            severity_default=Severity.HIGH,
            tags=("authorization", "iam", "cloud", "cis", "nist-800-53", "pci-dss", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Replace wildcard permissions with narrowly scoped actions/resources.",
            references=("CWE-266: Incorrect Privilege Assignment",),
        ),
        "CWE-269": VulnerabilityDefinition(
            id="CWE-269",
            cwe="CWE-269",
            name="Improper Privilege Management",
            description="Detects patterns indicating privilege creep and weak privilege lifecycle management.",
            severity_default=Severity.HIGH,
            tags=("authorization", "iam", "least-privilege", "cis", "nist-800-53", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion=(
                "Enforce least privilege, periodic entitlement review, and strict privileged access workflows."
            ),
            references=("CWE-269: Improper Privilege Management",),
        ),
        "CWE-276": VulnerabilityDefinition(
            id="CWE-276",
            cwe="CWE-276",
            name="Incorrect Default Permissions",
            description="Detects default-open permission posture in services, storage, or policy settings.",
            severity_default=Severity.HIGH,
            tags=("permissions", "misconfiguration", "cloud", "cis", "nist-800-53", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Use secure-by-default permissions and explicitly approve exceptions.",
            references=("CWE-276: Incorrect Default Permissions",),
        ),
        "CWE-290": VulnerabilityDefinition(
            id="CWE-290",
            cwe="CWE-290",
            name="Authentication Bypass by Spoofing",
            description="Detects trust in spoofable request headers or insecure identity-forwarding logic.",
            severity_default=Severity.HIGH,
            tags=("authentication", "identity", "owasp-top10-2025-a07"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Do not trust client-controlled identity headers without trusted gateway enforcement.",
            references=("CWE-290: Authentication Bypass by Spoofing",),
        ),
        "CWE-306": VulnerabilityDefinition(
            id="CWE-306",
            cwe="CWE-306",
            name="Missing Authentication for Critical Function",
            description="Detects critical routes/actions that appear to be exposed without authentication.",
            severity_default=Severity.CRITICAL,
            tags=("authentication", "authorization", "owasp-top10-2025-a01", "pci-dss", "hipaa"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Require authentication for all sensitive endpoints and admin operations.",
            references=("CWE-306: Missing Authentication for Critical Function",),
        ),
        "CWE-307": VulnerabilityDefinition(
            id="CWE-307",
            cwe="CWE-307",
            name="Improper Restriction of Excessive Authentication Attempts",
            description="Detects authentication code paths without apparent throttling/lockout controls.",
            severity_default=Severity.HIGH,
            tags=("authentication", "bruteforce", "nist-800-53", "pci-dss", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Add rate limiting, lockout/backoff, and anomaly detection for auth endpoints.",
            references=("CWE-307: Improper Restriction of Excessive Authentication Attempts",),
        ),
        "CWE-319": VulnerabilityDefinition(
            id="CWE-319",
            cwe="CWE-319",
            name="Cleartext Transmission of Sensitive Information",
            description="Detects sensitive data transport over non-TLS channels or insecure protocols.",
            severity_default=Severity.HIGH,
            tags=("transport", "tls", "pci-dss", "hipaa", "iso-27001", "owasp-top10-2025-a02"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Use TLS for all sensitive traffic and reject insecure transport paths.",
            references=("CWE-319: Cleartext Transmission of Sensitive Information",),
        ),
        "CWE-346": VulnerabilityDefinition(
            id="CWE-346",
            cwe="CWE-346",
            name="Origin Validation Error",
            description=(
                "Detects weak OAuth/SSO redirect and origin validation patterns, including wildcard redirects."
            ),
            severity_default=Severity.HIGH,
            tags=("oauth", "sso", "identity", "owasp-top10-2025-a01"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Allowlist redirect origins and enforce strict state/nonce/origin validation.",
            references=("CWE-346: Origin Validation Error",),
        ),
        "CWE-425": VulnerabilityDefinition(
            id="CWE-425",
            cwe="CWE-425",
            name="Forced Browsing",
            description="Detects direct object/path access patterns for protected resources without gate checks.",
            severity_default=Severity.HIGH,
            tags=("authorization", "owasp-top10-2025-a01"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Apply authorization checks uniformly to direct resource access paths.",
            references=("CWE-425: Direct Request ('Forced Browsing')",),
        ),
        "CWE-613": VulnerabilityDefinition(
            id="CWE-613",
            cwe="CWE-613",
            name="Insufficient Session Expiration",
            description="Detects long-lived or non-expiring sessions and weak session timeout controls.",
            severity_default=Severity.MEDIUM,
            tags=("session", "authentication", "pci-dss", "hipaa", "iso-27001"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Set bounded session lifetimes and rotate/invalidate tokens on auth boundary changes.",
            references=("CWE-613: Insufficient Session Expiration",),
        ),
        "CWE-942": VulnerabilityDefinition(
            id="CWE-942",
            cwe="CWE-942",
            name="Overly Permissive CORS Policy",
            description="Detects CORS settings that allow any origin with credentials or broad trust patterns.",
            severity_default=Severity.HIGH,
            tags=("web", "cors", "misconfiguration", "owasp-top10-2025-a01"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Restrict CORS origins explicitly and never combine wildcard origins with credentials.",
            references=("CWE-942: Overly Permissive Cross-domain Whitelist",),
        ),
        "CWE-1004": VulnerabilityDefinition(
            id="CWE-1004",
            cwe="CWE-1004",
            name="Sensitive Cookie Without HttpOnly Flag",
            description="Detects cookie settings that omit HttpOnly for session/authentication cookies.",
            severity_default=Severity.MEDIUM,
            tags=("web", "cookie", "session", "pci-dss", "owasp-top10-2025-a02"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Set HttpOnly (and Secure) on sensitive cookies.",
            references=("CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag",),
        ),
        "CWE-494": VulnerabilityDefinition(
            id="CWE-494",
            cwe="CWE-494",
            name="Download of Code Without Integrity Check",
            description=(
                "Detects patterns where code or dependencies are fetched and executed without "
                "integrity verification, including dependency confusion and unverified downloads."
            ),
            severity_default=Severity.HIGH,
            tags=("supply-chain", "integrity", "owasp-top10-2025-a08"),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion=(
                "Pin dependency versions with hashes, use lockfiles, verify package signatures, "
                "and avoid piping remote scripts directly to shell interpreters."
            ),
            references=("CWE-494: Download of Code Without Integrity Check",),
        ),
        "CWE-1104": VulnerabilityDefinition(
            id="CWE-1104",
            cwe="CWE-1104",
            name="Use of Unmaintained or Vulnerable Components",
            description=(
                "Detects dependencies and runtime versions associated with known CVEs or outdated, high-risk releases."
            ),
            severity_default=Severity.CRITICAL,
            tags=(
                "cve",
                "dependency",
                "supply-chain",
                "owasp-top10-2025-a06",
                "cis",
                "nist-800-53",
                "pci-dss",
                "hipaa",
                "iso-27001",
            ),
            languages=_ALL_SCANNER_LANGUAGES,
            fix_suggestion="Upgrade vulnerable dependencies/runtimes to patched versions and maintain update cadence.",
            references=("CWE-1104: Use of Unmaintained Third Party Components",),
        ),
        # --- New detectors: CWE Top 25 gaps + OWASP 2025 A03/A10 ---
        "CWE-787": VulnerabilityDefinition(
            id="CWE-787",
            cwe="CWE-787",
            name="Out-of-bounds Write",
            description=(
                "Detects unsafe memory write operations that may exceed allocated buffer boundaries, "
                "including C-style buffer functions, Rust unsafe pointer writes, Go unchecked slice "
                "assignments, and JS/TS typed-array operations without bounds checks."
            ),
            severity_default=Severity.CRITICAL,
            tags=("memory-safety", "owasp-top10-2025-a08", "cwe-top25-2024"),
            languages=("rust", "go", "javascript", "typescript"),
            vulnerable_example='strcpy(dest, user_input);  // no bounds check\n',
            secure_example='strncpy(dest, user_input, sizeof(dest) - 1);\ndest[sizeof(dest) - 1] = \'\\0\';\n',
            fix_suggestion=(
                "Use bounds-checked memory APIs (snprintf, strlcpy), safe abstractions, "
                "and validate buffer sizes before write operations."
            ),
            references=("CWE-787: Out-of-bounds Write",),
        ),
        "CWE-20": VulnerabilityDefinition(
            id="CWE-20",
            cwe="CWE-20",
            name="Improper Input Validation",
            description=(
                "Detects patterns where user-controlled input flows into sensitive sinks "
                "(file I/O, database, process spawning, redirects) without apparent validation, "
                "sanitization, or type coercion."
            ),
            severity_default=Severity.HIGH,
            tags=("input-validation", "owasp-top10-2025-a05", "cwe-top25-2024"),
            languages=_DEFAULT_LANGUAGES,
            vulnerable_example='cursor.execute("SELECT * FROM t WHERE id=" + request.args["id"])\n',
            secure_example='validated_id = int(request.args["id"])  # type coerce + validate\ncursor.execute("SELECT * FROM t WHERE id=%s", (validated_id,))\n',
            fix_suggestion=(
                "Validate all external inputs against expected types, ranges, and formats before "
                "passing them to sensitive operations. Use schema validation libraries."
            ),
            references=("CWE-20: Improper Input Validation",),
        ),
        "CWE-77": VulnerabilityDefinition(
            id="CWE-77",
            cwe="CWE-77",
            name="Command Injection",
            description=(
                "Detects generic command injection patterns including expression language injection, "
                "template command interpolation, and framework-specific command construction with "
                "unsanitized user input."
            ),
            severity_default=Severity.CRITICAL,
            tags=("injection", "owasp-top10-2025-a05", "cwe-top25-2024"),
            languages=_DEFAULT_LANGUAGES,
            vulnerable_example='Runtime.getRuntime().exec("cmd /c " + userInput);\n',
            secure_example='ProcessBuilder pb = new ProcessBuilder("cmd", "/c", sanitized);\n',
            fix_suggestion=(
                "Use parameterized command execution APIs, avoid string concatenation in commands, "
                "and validate/allowlist all user-supplied command components."
            ),
            references=("CWE-77: Improper Neutralization of Special Elements used in a Command",),
        ),
        "CWE-209": VulnerabilityDefinition(
            id="CWE-209",
            cwe="CWE-209",
            name="Error Message Information Exposure",
            description=(
                "Detects error handling that may leak stack traces, internal paths, database details, "
                "or other sensitive information to end users via HTTP responses or client output."
            ),
            severity_default=Severity.MEDIUM,
            tags=("information-disclosure", "error-handling", "owasp-top10-2025-a10", "cwe-top25-2024"),
            languages=_DEFAULT_LANGUAGES,
            vulnerable_example='except Exception as e:\n    return jsonify({"error": str(e)}), 500\n',
            secure_example='except Exception as e:\n    logger.error("Internal error: %s", e)\n    return jsonify({"error": "Internal server error"}), 500\n',
            fix_suggestion=(
                "Return generic error messages to clients. Log detailed error information "
                "server-side only. Disable debug mode in production."
            ),
            references=("CWE-209: Generation of Error Message Containing Sensitive Information",),
        ),
        "CWE-755": VulnerabilityDefinition(
            id="CWE-755",
            cwe="CWE-755",
            name="Improper Handling of Exceptional Conditions",
            description=(
                "Detects empty catch blocks, bare except clauses, swallowed exceptions, and "
                "fail-open error handling patterns that may mask security-critical failures."
            ),
            severity_default=Severity.MEDIUM,
            tags=("error-handling", "owasp-top10-2025-a10", "cwe-top25-2024"),
            languages=_DEFAULT_LANGUAGES,
            vulnerable_example='try:\n    authenticate(user)\nexcept:\n    pass  # silently fails\n',
            secure_example='try:\n    authenticate(user)\nexcept AuthError as e:\n    logger.warning("Auth failed: %s", e)\n    raise\n',
            fix_suggestion=(
                "Handle exceptions explicitly — log them, propagate them, or take corrective action. "
                "Never silently swallow exceptions. Use specific exception types."
            ),
            references=(
                "CWE-755: Improper Handling of Exceptional Conditions",
                "CWE-754: Improper Check for Unusual or Exceptional Conditions",
                "CWE-636: Not Failing Securely ('Failing Open')",
            ),
        ),
        "CWE-1395": VulnerabilityDefinition(
            id="CWE-1395",
            cwe="CWE-1395",
            name="Dependency Confusion / Typosquatting",
            description=(
                "Detects potential supply chain attack vectors including dependency confusion "
                "(mixed public/private registries without scoping), typosquatting (package names "
                "similar to popular packages), unpinned dependencies, and suspicious install scripts."
            ),
            severity_default=Severity.HIGH,
            tags=(
                "supply-chain",
                "dependency",
                "owasp-top10-2025-a03",
                "cwe-top25-2024",
                "cis",
                "nist-800-53",
            ),
            languages=_ALL_SCANNER_LANGUAGES,
            vulnerable_example='"dependencies": { "co1ors": "^1.0.0" }  // typosquat of "colors"\n',
            secure_example='"dependencies": { "colors": "1.4.0" }  // exact version, correct name\n',
            fix_suggestion=(
                "Pin dependency versions, use lockfiles with integrity hashes, scope private packages, "
                "verify package names against known registries, and audit install scripts."
            ),
            references=(
                "CWE-1395: Dependency on Vulnerable Third-Party Component",
                "OWASP A03:2025 Software Supply Chain Failures",
            ),
        ),
    }


_ADDITIONAL_VULNERABILITIES = _policy_and_supply_chain_definitions()


# ---------------------------------------------------------------------------
# Swift / iOS mobile security definitions
# ---------------------------------------------------------------------------

_SWIFT_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "SWIFT-001": VulnerabilityDefinition(
        id="SWIFT-001",
        cwe="CWE-798",
        name="Hardcoded Secret in Swift",
        description=(
            "Detects hardcoded API keys, passwords, tokens, or secrets in Swift source code. "
            "Secrets in source are extractable from compiled binaries."
        ),
        severity_default=Severity.CRITICAL,
        tags=("ios", "swift", "mobile", "secrets", "owasp-mobile-top10-2024-m1"),
        languages=("swift",),
        vulnerable_example='let apiKey = "sk-ABCDEF1234567890"\n',
        secure_example='let apiKey = KeychainWrapper.standard.string(forKey: "apiKey")\n',
        fix_suggestion="Store secrets in Keychain, a .xcconfig file (git-ignored), or a secrets manager.",
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
    "SWIFT-002": VulnerabilityDefinition(
        id="SWIFT-002",
        cwe="CWE-922",
        name="Sensitive Data in UserDefaults",
        description=(
            "Detects storage of sensitive data (passwords, tokens, credentials) in UserDefaults, "
            "which is stored as an unencrypted plist readable via device backup."
        ),
        severity_default=Severity.HIGH,
        tags=("ios", "swift", "mobile", "storage", "owasp-mobile-top10-2024-m9"),
        languages=("swift",),
        vulnerable_example='UserDefaults.standard.set(password, forKey: "userPassword")\n',
        secure_example='KeychainWrapper.standard.set(password, forKey: "userPassword")\n',
        fix_suggestion="Use Keychain Services (Security.framework) for sensitive values.",
        references=("CWE-922: Insecure Storage of Sensitive Information",),
    ),
    "SWIFT-003": VulnerabilityDefinition(
        id="SWIFT-003",
        cwe="CWE-532",
        name="Sensitive Data in Logs (Swift)",
        description=(
            "Detects logging of potentially sensitive data (passwords, tokens, secrets) "
            "via NSLog, print, or os_log in Swift code."
        ),
        severity_default=Severity.MEDIUM,
        tags=("ios", "swift", "mobile", "logging", "owasp-mobile-top10-2024-m6"),
        languages=("swift",),
        vulnerable_example='NSLog("User token: \\(authToken)")\n',
        secure_example='os_log("User authenticated", log: .default, type: .info)\n',
        fix_suggestion="Use os_log with .private redaction or remove sensitive data from log statements.",
        references=("CWE-532: Insertion of Sensitive Information into Log File",),
    ),
    "SWIFT-004": VulnerabilityDefinition(
        id="SWIFT-004",
        cwe="CWE-327",
        name="Weak Cryptography in Swift",
        description=(
            "Detects use of weak or deprecated cryptographic APIs (CC_MD5, CC_SHA1, "
            "DES, RC4, Insecure.MD5/SHA1) in Swift code."
        ),
        severity_default=Severity.HIGH,
        tags=("ios", "swift", "mobile", "crypto", "owasp-mobile-top10-2024-m10"),
        languages=("swift",),
        vulnerable_example='let hash = Insecure.MD5.hash(data: data)\n',
        secure_example='let hash = SHA256.hash(data: data)\n',
        fix_suggestion="Use CryptoKit (SHA256, AES.GCM, P256) or CommonCrypto with AES-256.",
        references=("CWE-327: Use of a Broken or Risky Cryptographic Algorithm",),
    ),
    "SWIFT-005": VulnerabilityDefinition(
        id="SWIFT-005",
        cwe="CWE-295",
        name="Missing Certificate Pinning",
        description=(
            "Detects URLSession usage without SSL/TLS certificate pinning, which makes "
            "the app vulnerable to man-in-the-middle attacks."
        ),
        severity_default=Severity.MEDIUM,
        tags=("ios", "swift", "mobile", "network", "owasp-mobile-top10-2024-m5"),
        languages=("swift",),
        vulnerable_example='let session = URLSession(configuration: .default)\n',
        secure_example=(
            'let session = URLSession(configuration: .default, delegate: PinningDelegate(), delegateQueue: nil)\n'
        ),
        fix_suggestion=(
            "Implement URLSessionDelegate.urlSession(_:didReceive:completionHandler:) "
            "to validate server certificates against pinned keys."
        ),
        references=("CWE-295: Improper Certificate Validation",),
    ),
    "SWIFT-006": VulnerabilityDefinition(
        id="SWIFT-006",
        cwe="CWE-79",
        name="Insecure WKWebView Configuration",
        description=(
            "Detects WKWebView with JavaScript enabled loading dynamic content, which "
            "may be vulnerable to cross-site scripting or content injection."
        ),
        severity_default=Severity.HIGH,
        tags=("ios", "swift", "mobile", "webview", "owasp-mobile-top10-2024-m8"),
        languages=("swift",),
        vulnerable_example=(
            'let config = WKWebViewConfiguration()\n'
            'config.preferences.javaScriptEnabled = true\n'
            'webView.load(URLRequest(url: untrustedURL))\n'
        ),
        secure_example=(
            'config.preferences.javaScriptEnabled = false  // for static content\n'
            '// or validate URL against allowlist before loading\n'
        ),
        fix_suggestion=(
            "Disable JavaScript for static content. For dynamic content, validate URLs "
            "against an allowlist and implement WKNavigationDelegate."
        ),
        references=("CWE-79: Improper Neutralization of Input During Web Page Generation",),
    ),
    "SWIFT-007": VulnerabilityDefinition(
        id="SWIFT-007",
        cwe="CWE-311",
        name="Insecure Keychain Accessibility",
        description=(
            "Detects Keychain items stored with kSecAttrAccessibleAlways or "
            "kSecAttrAccessibleAlwaysThisDeviceOnly, which are accessible when "
            "the device is locked."
        ),
        severity_default=Severity.HIGH,
        tags=("ios", "swift", "mobile", "storage", "owasp-mobile-top10-2024-m9"),
        languages=("swift",),
        vulnerable_example='query[kSecAttrAccessible] = kSecAttrAccessibleAlways\n',
        secure_example='query[kSecAttrAccessible] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly\n',
        fix_suggestion=(
            "Use kSecAttrAccessibleWhenUnlockedThisDeviceOnly or "
            "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly."
        ),
        references=("CWE-311: Missing Encryption of Sensitive Data",),
    ),
    "SWIFT-008": VulnerabilityDefinition(
        id="SWIFT-008",
        cwe="CWE-200",
        name="Clipboard Exposure of Sensitive Data",
        description=(
            "Detects sensitive data being copied to the system clipboard via "
            "UIPasteboard.general, which is accessible by other apps."
        ),
        severity_default=Severity.MEDIUM,
        tags=("ios", "swift", "mobile", "owasp-mobile-top10-2024-m6"),
        languages=("swift",),
        vulnerable_example='UIPasteboard.general.string = userPassword\n',
        secure_example=(
            'UIPasteboard.general.setItems([[UIPasteboard.typeAutomatic: password]], '
            'options: [.expirationDate: Date().addingTimeInterval(60)])\n'
        ),
        fix_suggestion="Set clipboard expiration or use local-only pasteboard.",
        references=("CWE-200: Exposure of Sensitive Information to an Unauthorized Actor",),
    ),
    "SWIFT-009": VulnerabilityDefinition(
        id="SWIFT-009",
        cwe="CWE-89",
        name="SQL Injection in Swift",
        description=(
            "Detects SQL queries built with string interpolation in Swift, which "
            "may be vulnerable to SQL injection attacks."
        ),
        severity_default=Severity.CRITICAL,
        tags=("ios", "swift", "mobile", "injection", "owasp-mobile-top10-2024-m4"),
        languages=("swift",),
        vulnerable_example='db.execute("SELECT * FROM users WHERE id = \\(userId)")\n',
        secure_example='db.execute("SELECT * FROM users WHERE id = ?", [userId])\n',
        fix_suggestion="Use parameterized queries with ? placeholders instead of string interpolation.",
        references=("CWE-89: Improper Neutralization of Special Elements used in an SQL Command",),
    ),
    "SWIFT-010": VulnerabilityDefinition(
        id="SWIFT-010",
        cwe="CWE-319",
        name="Insecure HTTP URL (Swift)",
        description=(
            "Detects use of plain HTTP URLs (non-TLS) in Swift network code, which "
            "transmits data in cleartext."
        ),
        severity_default=Severity.MEDIUM,
        tags=("ios", "swift", "mobile", "network", "owasp-mobile-top10-2024-m5"),
        languages=("swift",),
        vulnerable_example='let url = URL(string: "http://api.example.com/data")\n',
        secure_example='let url = URL(string: "https://api.example.com/data")\n',
        fix_suggestion="Use HTTPS (TLS) for all network communication.",
        references=("CWE-319: Cleartext Transmission of Sensitive Information",),
    ),
    "PLIST-001": VulnerabilityDefinition(
        id="PLIST-001",
        cwe="CWE-319",
        name="App Transport Security Disabled",
        description=(
            "Detects NSAllowsArbitraryLoads set to true in Info.plist, which disables "
            "App Transport Security and allows insecure HTTP connections."
        ),
        severity_default=Severity.HIGH,
        tags=("ios", "plist", "mobile", "network", "owasp-mobile-top10-2024-m5"),
        languages=("plist",),
        vulnerable_example="<key>NSAllowsArbitraryLoads</key>\n<true/>",
        secure_example="<key>NSAllowsArbitraryLoads</key>\n<false/>",
        fix_suggestion=(
            "Remove NSAllowsArbitraryLoads or set to false. Use NSExceptionDomains "
            "for specific domains that require HTTP."
        ),
        references=("Apple ATS Documentation",),
    ),
    "PLIST-002": VulnerabilityDefinition(
        id="PLIST-002",
        cwe="CWE-200",
        name="Excessive Privacy Permissions",
        description="Detects apps requesting an unusually high number of privacy permissions.",
        severity_default=Severity.LOW,
        tags=("ios", "plist", "mobile", "privacy"),
        languages=("plist",),
        fix_suggestion="Only request permissions your app actively uses.",
        references=("Apple Privacy Documentation",),
    ),
    "PLIST-003": VulnerabilityDefinition(
        id="PLIST-003",
        cwe="CWE-284",
        name="Custom URL Scheme Registered",
        description=(
            "Detects apps registering custom URL schemes that may be vulnerable to "
            "URL scheme hijacking if incoming URLs are not validated."
        ),
        severity_default=Severity.LOW,
        tags=("ios", "plist", "mobile"),
        languages=("plist",),
        fix_suggestion="Validate all incoming URL parameters. Consider using Universal Links instead.",
        references=("CWE-284: Improper Access Control",),
    ),
    "PLIST-005": VulnerabilityDefinition(
        id="PLIST-005",
        cwe="CWE-732",
        name="Overly Broad Entitlement",
        description=(
            "Detects overly broad entitlements in .entitlements files that grant "
            "more capabilities than necessary."
        ),
        severity_default=Severity.MEDIUM,
        tags=("ios", "macos", "plist", "mobile"),
        languages=("plist",),
        fix_suggestion="Review entitlements and remove any that are not required.",
        references=("CWE-732: Incorrect Permission Assignment for Critical Resource",),
    ),
}


# ---------------------------------------------------------------------------
# Kotlin / Android security definitions
# ---------------------------------------------------------------------------

_KOTLIN_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "KOTLIN-001": VulnerabilityDefinition(
        id="KOTLIN-001", cwe="CWE-922", name="Sensitive Data in SharedPreferences",
        description="Detects storage of sensitive data in SharedPreferences (unencrypted XML on disk).",
        severity_default=Severity.CRITICAL,
        tags=("android", "kotlin", "mobile", "storage", "owasp-mobile-top10-2024-m9"),
        languages=("kotlin",),
        fix_suggestion="Use EncryptedSharedPreferences or Android Keystore for sensitive values.",
        references=("CWE-922: Insecure Storage of Sensitive Information",),
    ),
    "KOTLIN-002": VulnerabilityDefinition(
        id="KOTLIN-002", cwe="CWE-798", name="Hardcoded Secret in Kotlin",
        description="Detects hardcoded API keys, passwords, or tokens in Kotlin source code.",
        severity_default=Severity.CRITICAL,
        tags=("android", "kotlin", "mobile", "secrets", "owasp-mobile-top10-2024-m1"),
        languages=("kotlin",),
        fix_suggestion="Store secrets in Android Keystore, gradle.properties (git-ignored), or a secrets manager.",
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
    "KOTLIN-003": VulnerabilityDefinition(
        id="KOTLIN-003", cwe="CWE-926", name="Exported Android Component",
        description="Detects Android components exported without permission protection.",
        severity_default=Severity.HIGH,
        tags=("android", "kotlin", "mobile", "owasp-mobile-top10-2024-m1"),
        languages=("kotlin",),
        fix_suggestion="Set android:exported=false or add android:permission to protect exported components.",
        references=("CWE-926: Improper Export of Android Application Components",),
    ),
    "KOTLIN-004": VulnerabilityDefinition(
        id="KOTLIN-004", cwe="CWE-79", name="Insecure WebView (Android)",
        description="Detects WebView with JavaScript enabled or addJavascriptInterface, enabling XSS.",
        severity_default=Severity.HIGH,
        tags=("android", "kotlin", "mobile", "webview", "owasp-mobile-top10-2024-m8"),
        languages=("kotlin",),
        fix_suggestion="Disable JavaScript for static content. Avoid addJavascriptInterface on API < 17.",
        references=("CWE-79: Cross-site Scripting",),
    ),
    "KOTLIN-005": VulnerabilityDefinition(
        id="KOTLIN-005", cwe="CWE-532", name="Sensitive Data in Android Logs",
        description="Detects logging of sensitive data via Log.d/i/v/w/e in Kotlin code.",
        severity_default=Severity.MEDIUM,
        tags=("android", "kotlin", "mobile", "logging", "owasp-mobile-top10-2024-m6"),
        languages=("kotlin",),
        fix_suggestion="Remove sensitive data from log statements. Use ProGuard/R8 to strip Log calls in release.",
        references=("CWE-532: Insertion of Sensitive Information into Log File",),
    ),
    "KOTLIN-006": VulnerabilityDefinition(
        id="KOTLIN-006", cwe="CWE-295", name="Insecure TrustManager (Android)",
        description="Detects custom TrustManager that accepts all certificates (MITM vulnerability).",
        severity_default=Severity.CRITICAL,
        tags=("android", "kotlin", "mobile", "network", "owasp-mobile-top10-2024-m5"),
        languages=("kotlin",),
        fix_suggestion="Use the default TrustManager or implement proper certificate pinning.",
        references=("CWE-295: Improper Certificate Validation",),
    ),
    "KOTLIN-007": VulnerabilityDefinition(
        id="KOTLIN-007", cwe="CWE-312", name="External Storage for Sensitive Data",
        description="Detects use of external storage (world-readable) for potentially sensitive data.",
        severity_default=Severity.HIGH,
        tags=("android", "kotlin", "mobile", "storage", "owasp-mobile-top10-2024-m9"),
        languages=("kotlin",),
        fix_suggestion="Use internal storage (getFilesDir()) or EncryptedFile for sensitive data.",
        references=("CWE-312: Cleartext Storage of Sensitive Information",),
    ),
    "KOTLIN-008": VulnerabilityDefinition(
        id="KOTLIN-008", cwe="CWE-327", name="Weak Cryptography in Kotlin",
        description="Detects use of weak crypto (DES, ECB, MD5, SHA-1) in Kotlin/Java code.",
        severity_default=Severity.HIGH,
        tags=("android", "kotlin", "mobile", "crypto", "owasp-mobile-top10-2024-m10"),
        languages=("kotlin",),
        fix_suggestion="Use AES/GCM/NoPadding, SHA-256+, or Jetpack Security crypto library.",
        references=("CWE-327: Use of a Broken or Risky Cryptographic Algorithm",),
    ),
    "KOTLIN-009": VulnerabilityDefinition(
        id="KOTLIN-009", cwe="CWE-89", name="SQL Injection in Kotlin",
        description="Detects SQL queries with string interpolation/concatenation in Kotlin.",
        severity_default=Severity.CRITICAL,
        tags=("android", "kotlin", "mobile", "injection", "owasp-mobile-top10-2024-m4"),
        languages=("kotlin",),
        fix_suggestion="Use parameterized queries with ? placeholders or Room DAO.",
        references=("CWE-89: SQL Injection",),
    ),
    "KOTLIN-010": VulnerabilityDefinition(
        id="KOTLIN-010", cwe="CWE-319", name="Cleartext Traffic (Android)",
        description="Detects plain HTTP URLs or cleartext traffic configuration in Android apps.",
        severity_default=Severity.MEDIUM,
        tags=("android", "kotlin", "mobile", "network", "owasp-mobile-top10-2024-m5"),
        languages=("kotlin",),
        fix_suggestion="Use HTTPS for all network communication. Set usesCleartextTraffic=false.",
        references=("CWE-319: Cleartext Transmission of Sensitive Information",),
    ),
}


# ---------------------------------------------------------------------------
# CI/CD pipeline security definitions
# ---------------------------------------------------------------------------

_CICD_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "CICD-001": VulnerabilityDefinition(
        id="CICD-001", cwe="CWE-78", name="Command Injection in CI/CD Pipeline",
        description="Detects user-controlled GitHub event data injected into shell commands.",
        severity_default=Severity.CRITICAL,
        tags=("cicd", "github-actions", "supply-chain", "injection", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Use an intermediate environment variable instead of inline expansion of event data.",
        references=("CWE-78: OS Command Injection",),
    ),
    "CICD-002": VulnerabilityDefinition(
        id="CICD-002", cwe="CWE-200", name="Secrets Exposed in CI/CD Logs",
        description="Detects secrets being echoed or printed in CI/CD pipeline logs.",
        severity_default=Severity.HIGH,
        tags=("cicd", "github-actions", "secrets", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Never echo secrets. Use ::add-mask:: to mask values if needed.",
        references=("CWE-200: Exposure of Sensitive Information",),
    ),
    "CICD-003": VulnerabilityDefinition(
        id="CICD-003", cwe="CWE-829", name="Unsafe pull_request_target Trigger",
        description="Detects pull_request_target with checkout of PR head (runs untrusted code with write perms).",
        severity_default=Severity.HIGH,
        tags=("cicd", "github-actions", "supply-chain", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Use pull_request event instead, or avoid checking out PR head ref.",
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
    "CICD-004": VulnerabilityDefinition(
        id="CICD-004", cwe="CWE-250", name="Excessive CI/CD Permissions",
        description="Detects overly broad workflow permissions (write-all, contents: write).",
        severity_default=Severity.HIGH,
        tags=("cicd", "github-actions", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Use least-privilege permissions. Only grant specific permissions needed.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "CICD-005": VulnerabilityDefinition(
        id="CICD-005", cwe="CWE-829", name="Unpinned Action Version",
        description="Detects GitHub Actions using mutable tags (v1, main) instead of SHA-pinned versions.",
        severity_default=Severity.MEDIUM,
        tags=("cicd", "github-actions", "supply-chain", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Pin actions to full commit SHA: uses: owner/repo@abc123...",
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
    "CICD-006": VulnerabilityDefinition(
        id="CICD-006", cwe="CWE-798", name="Hardcoded Secret in CI/CD Workflow",
        description="Detects literal API keys or passwords in CI/CD workflow files.",
        severity_default=Severity.CRITICAL,
        tags=("cicd", "github-actions", "secrets", "owasp-top10-2025-a08"),
        languages=("yaml",),
        fix_suggestion="Use repository secrets (${{ secrets.MY_SECRET }}) instead of literal values.",
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
    "CICD-007": VulnerabilityDefinition(
        id="CICD-007", cwe="CWE-250", name="Unsafe Artifact Handling",
        description="Detects potential artifact poisoning via unscoped upload/download.",
        severity_default=Severity.MEDIUM,
        tags=("cicd", "github-actions", "supply-chain"),
        languages=("yaml",),
        fix_suggestion="Always specify explicit artifact names and validate contents after download.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "CICD-008": VulnerabilityDefinition(
        id="CICD-008", cwe="CWE-116", name="Script Injection in GitLab CI",
        description="Detects user-controlled CI variables used unsafely in GitLab CI scripts.",
        severity_default=Severity.HIGH,
        tags=("cicd", "gitlab-ci", "injection"),
        languages=("yaml",),
        fix_suggestion="Validate and sanitize CI variables before using them in script blocks.",
        references=("CWE-116: Improper Encoding or Escaping of Output",),
    ),
}


# ---------------------------------------------------------------------------
# React / Frontend security definitions
# ---------------------------------------------------------------------------

_REACT_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "REACT-001": VulnerabilityDefinition(
        id="REACT-001", cwe="CWE-79", name="dangerouslySetInnerHTML",
        description="Detects use of dangerouslySetInnerHTML which bypasses React's XSS protections.",
        severity_default=Severity.HIGH,
        tags=("react", "frontend", "xss", "owasp-top10-2025-a03"),
        languages=("javascript", "typescript"),
        fix_suggestion="Use DOMPurify.sanitize() or avoid injecting raw HTML.",
        references=("CWE-79: Cross-site Scripting",),
    ),
    "REACT-002": VulnerabilityDefinition(
        id="REACT-002", cwe="CWE-95", name="eval() or Dynamic Code Execution",
        description="Detects eval(), new Function(), or string-based setTimeout/setInterval.",
        severity_default=Severity.CRITICAL,
        tags=("react", "frontend", "injection", "owasp-top10-2025-a03"),
        languages=("javascript", "typescript"),
        fix_suggestion="Avoid eval() and dynamic code execution. Use safe alternatives.",
        references=("CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code",),
    ),
    "REACT-003": VulnerabilityDefinition(
        id="REACT-003", cwe="CWE-922", name="Sensitive Data in localStorage/sessionStorage",
        description="Detects storage of tokens, passwords, or secrets in browser storage (XSS-accessible).",
        severity_default=Severity.HIGH,
        tags=("react", "frontend", "storage", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Use httpOnly cookies for auth tokens. Never store secrets in localStorage.",
        references=("CWE-922: Insecure Storage of Sensitive Information",),
    ),
    "REACT-004": VulnerabilityDefinition(
        id="REACT-004", cwe="CWE-346", name="postMessage Without Origin Validation",
        description="Detects window.postMessage or message event listeners without origin checking.",
        severity_default=Severity.MEDIUM,
        tags=("react", "frontend", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Always check event.origin in message event handlers before processing data.",
        references=("CWE-346: Origin Validation Error",),
    ),
    "REACT-005": VulnerabilityDefinition(
        id="REACT-005", cwe="CWE-601", name="Open Redirect",
        description="Detects potential open redirect via window.location assignment with user input.",
        severity_default=Severity.MEDIUM,
        tags=("react", "frontend", "redirect", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Validate redirect URLs against an allowlist of trusted domains.",
        references=("CWE-601: URL Redirection to Untrusted Site",),
    ),
    "REACT-006": VulnerabilityDefinition(
        id="REACT-006", cwe="CWE-352", name="Missing CSRF Protection",
        description="Detects fetch/XHR POST/PUT/DELETE without CSRF token headers.",
        severity_default=Severity.MEDIUM,
        tags=("react", "frontend", "csrf", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Include CSRF token in request headers for state-changing operations.",
        references=("CWE-352: Cross-Site Request Forgery",),
    ),
    "REACT-007": VulnerabilityDefinition(
        id="REACT-007", cwe="CWE-16", name="Permissive CORS Configuration",
        description="Detects Access-Control-Allow-Origin: * or cors({ origin: '*' }).",
        severity_default=Severity.LOW,
        tags=("react", "frontend", "cors", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Restrict CORS to specific trusted origins instead of wildcard.",
        references=("CWE-16: Configuration",),
    ),
    "REACT-008": VulnerabilityDefinition(
        id="REACT-008", cwe="CWE-312", name="Client-Side Secret Exposure",
        description="Detects API keys or secrets in client-side JS/TS code (REACT_APP_, NEXT_PUBLIC_, VITE_).",
        severity_default=Severity.HIGH,
        tags=("react", "frontend", "secrets", "owasp-top10-2025-a07"),
        languages=("javascript", "typescript"),
        fix_suggestion="Move secrets to server-side. Use API routes/proxies instead of exposing keys.",
        references=("CWE-312: Cleartext Storage of Sensitive Information",),
    ),
}


# ---------------------------------------------------------------------------
# Kubernetes / Docker Compose security definitions
# ---------------------------------------------------------------------------

_K8S_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "K8S-001": VulnerabilityDefinition(
        id="K8S-001", cwe="CWE-250", name="Privileged Container",
        description="Detects containers running in privileged mode (full host access).",
        severity_default=Severity.CRITICAL,
        tags=("kubernetes", "docker", "infrastructure", "owasp-top10-2025-a05"),
        languages=("yaml", "dockercompose"),
        fix_suggestion="Remove privileged: true. Use specific capabilities instead.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "K8S-002": VulnerabilityDefinition(
        id="K8S-002", cwe="CWE-250", name="Container Running as Root",
        description="Detects containers running as root user (runAsUser: 0 or runAsNonRoot: false).",
        severity_default=Severity.HIGH,
        tags=("kubernetes", "infrastructure", "owasp-top10-2025-a05"),
        languages=("yaml",),
        fix_suggestion="Set runAsNonRoot: true and runAsUser to a non-zero UID.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "K8S-003": VulnerabilityDefinition(
        id="K8S-003", cwe="CWE-770", name="Missing Resource Limits",
        description="Detects K8s workloads without CPU/memory resource limits (DoS risk).",
        severity_default=Severity.MEDIUM,
        tags=("kubernetes", "infrastructure"),
        languages=("yaml",),
        fix_suggestion="Add resources.limits.cpu and resources.limits.memory to all containers.",
        references=("CWE-770: Allocation of Resources Without Limits or Throttling",),
    ),
    "K8S-004": VulnerabilityDefinition(
        id="K8S-004", cwe="CWE-250", name="Host Namespace Sharing",
        description="Detects hostNetwork, hostPID, or hostIPC enabled (container escape risk).",
        severity_default=Severity.HIGH,
        tags=("kubernetes", "infrastructure", "owasp-top10-2025-a05"),
        languages=("yaml",),
        fix_suggestion="Disable hostNetwork, hostPID, and hostIPC unless absolutely required.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "K8S-005": VulnerabilityDefinition(
        id="K8S-005", cwe="CWE-732", name="Writable Root Filesystem",
        description="Detects containers without readOnlyRootFilesystem (malware persistence risk).",
        severity_default=Severity.MEDIUM,
        tags=("kubernetes", "infrastructure"),
        languages=("yaml",),
        fix_suggestion="Set readOnlyRootFilesystem: true and use emptyDir volumes for writable paths.",
        references=("CWE-732: Incorrect Permission Assignment for Critical Resource",),
    ),
    "K8S-006": VulnerabilityDefinition(
        id="K8S-006", cwe="CWE-250", name="Dangerous Container Capabilities",
        description="Detects containers with dangerous Linux capabilities (SYS_ADMIN, NET_ADMIN, ALL).",
        severity_default=Severity.HIGH,
        tags=("kubernetes", "infrastructure", "owasp-top10-2025-a05"),
        languages=("yaml",),
        fix_suggestion="Drop ALL capabilities and add only specific ones needed.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "K8S-007": VulnerabilityDefinition(
        id="K8S-007", cwe="CWE-798", name="Hardcoded Secret in K8s Manifest",
        description="Detects literal passwords, tokens, or API keys in Kubernetes YAML manifests.",
        severity_default=Severity.CRITICAL,
        tags=("kubernetes", "infrastructure", "secrets", "owasp-top10-2025-a07"),
        languages=("yaml",),
        fix_suggestion="Use Kubernetes Secrets, external secret operators, or Vault.",
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
    "COMPOSE-001": VulnerabilityDefinition(
        id="COMPOSE-001", cwe="CWE-250", name="Privileged Docker Compose Service",
        description="Detects Docker Compose services running in privileged mode.",
        severity_default=Severity.CRITICAL,
        tags=("docker", "compose", "infrastructure", "owasp-top10-2025-a05"),
        languages=("yaml", "dockercompose"),
        fix_suggestion="Remove privileged: true from service configuration.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "COMPOSE-002": VulnerabilityDefinition(
        id="COMPOSE-002", cwe="CWE-250", name="Host Network in Docker Compose",
        description="Detects Docker Compose services using host network mode.",
        severity_default=Severity.HIGH,
        tags=("docker", "compose", "infrastructure"),
        languages=("yaml", "dockercompose"),
        fix_suggestion="Use a custom bridge network instead of host network mode.",
        references=("CWE-250: Execution with Unnecessary Privileges",),
    ),
    "COMPOSE-003": VulnerabilityDefinition(
        id="COMPOSE-003", cwe="CWE-798", name="Hardcoded Secret in Docker Compose",
        description="Detects literal passwords or secrets in Docker Compose environment variables.",
        severity_default=Severity.HIGH,
        tags=("docker", "compose", "infrastructure", "secrets"),
        languages=("yaml", "dockercompose"),
        fix_suggestion="Use .env files (git-ignored) or Docker secrets instead of literal values.",
        references=("CWE-798: Use of Hard-coded Credentials",),
    ),
}

_EVAL_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "EVAL-001": VulnerabilityDefinition(
        id="EVAL-001", cwe="CWE-95", name="Python Eval/Exec Injection",
        description="Detects use of eval(), exec(), compile() that can execute arbitrary code from untrusted input.",
        severity_default=Severity.CRITICAL,
        tags=("injection", "owasp-top10-2025-a03", "owasp-mobile-top10-2024-m4"),
        languages=("python",),
        fix_suggestion="Use ast.literal_eval() for data parsing or a safe sandbox/allowlist approach.",
        references=("CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code",),
    ),
    "EVAL-002": VulnerabilityDefinition(
        id="EVAL-002", cwe="CWE-95", name="Ruby Eval Injection",
        description="Detects use of eval, instance_eval, class_eval, send with dynamic input in Ruby.",
        severity_default=Severity.CRITICAL,
        tags=("injection", "owasp-top10-2025-a03"),
        languages=("ruby",),
        fix_suggestion="Avoid eval with user input. Use safe alternatives like case/when or method allowlists.",
        references=("CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code",),
    ),
    "EVAL-003": VulnerabilityDefinition(
        id="EVAL-003", cwe="CWE-95", name="PHP Eval/Assert Injection",
        description="Detects use of eval(), assert(), create_function(), preg_replace /e modifier in PHP.",
        severity_default=Severity.CRITICAL,
        tags=("injection", "owasp-top10-2025-a03"),
        languages=("php",),
        fix_suggestion="Remove eval(). Use preg_replace_callback() instead of /e modifier.",
        references=("CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code",),
    ),
    "EVAL-004": VulnerabilityDefinition(
        id="EVAL-004", cwe="CWE-94", name="Unsafe Deserialization (pickle/marshal)",
        description="Detects pickle.loads/marshal.loads which execute arbitrary code on untrusted data.",
        severity_default=Severity.CRITICAL,
        tags=("injection", "deserialization", "owasp-top10-2025-a08"),
        languages=("python",),
        fix_suggestion="Use json.loads() or a safe serialization format. Never unpickle untrusted data.",
        references=("CWE-94: Improper Control of Generation of Code",),
    ),
}

_INCLUSION_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "INCL-001": VulnerabilityDefinition(
        id="INCL-001", cwe="CWE-829", name="Missing Subresource Integrity (SRI)",
        description="Detects external scripts/stylesheets loaded without SRI hash verification.",
        severity_default=Severity.MEDIUM,
        tags=("supply-chain", "owasp-top10-2025-a08", "owasp-top10-2025-a06"),
        languages=("html", "javascript", "typescript"),
        fix_suggestion='Add integrity="sha384-..." and crossorigin="anonymous" attributes.',
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
    "INCL-002": VulnerabilityDefinition(
        id="INCL-002", cwe="CWE-829", name="Dynamic Require/Import with Variable",
        description="Detects require() or import() with variable paths that can load arbitrary modules.",
        severity_default=Severity.HIGH,
        tags=("supply-chain", "injection", "owasp-top10-2025-a08"),
        languages=("javascript", "typescript"),
        fix_suggestion="Use static import paths or validate against an allowlist.",
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
    "INCL-003": VulnerabilityDefinition(
        id="INCL-003", cwe="CWE-829", name="Python Dynamic Import with Variable",
        description="Detects importlib.import_module() or __import__() with variable module names.",
        severity_default=Severity.HIGH,
        tags=("supply-chain", "injection", "owasp-top10-2025-a08"),
        languages=("python",),
        fix_suggestion="Validate module names against an allowlist before importing dynamically.",
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
    "INCL-004": VulnerabilityDefinition(
        id="INCL-004", cwe="CWE-829", name="HTTP Resource Loading (No TLS)",
        description="Detects resources loaded over insecure HTTP where MITM can inject malicious content.",
        severity_default=Severity.MEDIUM,
        tags=("supply-chain", "owasp-top10-2025-a08"),
        languages=("html",),
        fix_suggestion="Change http:// to https:// for all external resource URLs.",
        references=("CWE-829: Inclusion of Functionality from Untrusted Control Sphere",),
    ),
}

_LOGGING_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "LOG-001": VulnerabilityDefinition(
        id="LOG-001", cwe="CWE-778", name="Empty Catch/Except Block",
        description="Detects empty catch/except blocks that silently swallow errors.",
        severity_default=Severity.MEDIUM,
        tags=("logging", "monitoring", "owasp-top10-2025-a09"),
        languages=("python", "javascript", "typescript", "go", "java", "kotlin"),
        fix_suggestion="Log the exception: logger.exception() or console.error(err).",
        references=("CWE-778: Insufficient Logging",),
    ),
    "LOG-002": VulnerabilityDefinition(
        id="LOG-002", cwe="CWE-778", name="Catch Block Without Logging",
        description="Detects catch blocks that handle errors without any logging.",
        severity_default=Severity.LOW,
        tags=("logging", "monitoring", "owasp-top10-2025-a09"),
        languages=("python", "javascript", "typescript", "go", "java", "kotlin"),
        fix_suggestion="Add logging to track errors in production.",
        references=("CWE-778: Insufficient Logging",),
    ),
    "LOG-003": VulnerabilityDefinition(
        id="LOG-003", cwe="CWE-778", name="Authentication Without Audit Logging",
        description="Detects authentication functions without any audit logging for security monitoring.",
        severity_default=Severity.MEDIUM,
        tags=("logging", "monitoring", "authentication", "owasp-top10-2025-a09"),
        languages=("python", "javascript", "typescript", "go", "java", "kotlin"),
        fix_suggestion="Add audit logging for authentication events (login success/failure).",
        references=("CWE-778: Insufficient Logging",),
    ),
}

_MANIFEST_VULNERABILITIES: dict[str, VulnerabilityDefinition] = {
    "MANIFEST-001": VulnerabilityDefinition(
        id="MANIFEST-001", cwe="CWE-926", name="Exported Component Without Protection",
        description="Detects Android exported components (activity, service, receiver, provider) without permission protection.",
        severity_default=Severity.HIGH,
        tags=("android", "mobile", "owasp-mobile-top10-2024-m1", "owasp-mobile-top10-2024-m8"),
        languages=("xml",),
        fix_suggestion='Add android:permission="..." or set android:exported="false".',
        references=("CWE-926: Improper Export of Android Application Components",),
    ),
    "MANIFEST-002": VulnerabilityDefinition(
        id="MANIFEST-002", cwe="CWE-276", name="Excessive Android Permissions",
        description="Detects apps requesting an excessive number of dangerous permissions.",
        severity_default=Severity.LOW,
        tags=("android", "mobile", "permissions", "owasp-mobile-top10-2024-m1"),
        languages=("xml",),
        fix_suggestion="Only request permissions your app actively uses.",
        references=("CWE-276: Incorrect Default Permissions",),
    ),
    "MANIFEST-003": VulnerabilityDefinition(
        id="MANIFEST-003", cwe="CWE-319", name="Cleartext Traffic Allowed",
        description="Detects usesCleartextTraffic=true allowing unencrypted HTTP traffic.",
        severity_default=Severity.HIGH,
        tags=("android", "mobile", "owasp-mobile-top10-2024-m9"),
        languages=("xml",),
        fix_suggestion='Set android:usesCleartextTraffic="false" and use network_security_config.xml for exceptions.',
        references=("CWE-319: Cleartext Transmission of Sensitive Information",),
    ),
    "MANIFEST-004": VulnerabilityDefinition(
        id="MANIFEST-004", cwe="CWE-693", name="Debuggable Application",
        description="Detects android:debuggable=true which exposes app internals in production.",
        severity_default=Severity.CRITICAL,
        tags=("android", "mobile", "owasp-mobile-top10-2024-m2"),
        languages=("xml",),
        fix_suggestion='Remove android:debuggable="true" or ensure it is only in debug build variants.',
        references=("CWE-693: Protection Mechanism Failure",),
    ),
    "MANIFEST-005": VulnerabilityDefinition(
        id="MANIFEST-005", cwe="CWE-693", name="Application Backup Allowed",
        description="Detects allowBackup=true which lets sensitive data be extracted via adb backup.",
        severity_default=Severity.MEDIUM,
        tags=("android", "mobile", "owasp-mobile-top10-2024-m2"),
        languages=("xml",),
        fix_suggestion='Set android:allowBackup="false" or use fullBackupContent to exclude sensitive files.',
        references=("CWE-693: Protection Mechanism Failure",),
    ),
}


def normalize_rule_id(rule_id: str) -> str:
    """Normalize inputs like cwe208 / CWE208 / CWE-208 to canonical CWE-208."""
    value = rule_id.strip().upper()
    m = re.fullmatch(r"CWE[-_ ]?(\d+)", value)
    if m:
        return f"CWE-{m.group(1)}"
    return value


@lru_cache(maxsize=1)
def _known_vulnerabilities() -> dict[str, VulnerabilityDefinition]:
    # Centralized in-repo catalog; scanner behavior is independent of external repos.
    merged = dict(_BASE_VULNERABILITIES)
    merged.update(_EXTENDED_VULNERABILITIES)
    merged.update(_ADDITIONAL_VULNERABILITIES)
    merged.update(_SWIFT_VULNERABILITIES)
    merged.update(_KOTLIN_VULNERABILITIES)
    merged.update(_CICD_VULNERABILITIES)
    merged.update(_REACT_VULNERABILITIES)
    merged.update(_K8S_VULNERABILITIES)
    merged.update(_EVAL_VULNERABILITIES)
    merged.update(_INCLUSION_VULNERABILITIES)
    merged.update(_LOGGING_VULNERABILITIES)
    merged.update(_MANIFEST_VULNERABILITIES)
    return merged


def reset_vulnerability_cache() -> None:
    _known_vulnerabilities.cache_clear()


def get_vulnerability(rule_id: str) -> VulnerabilityDefinition:
    normalized = normalize_rule_id(rule_id)
    definition = _known_vulnerabilities().get(normalized)
    if definition is None:
        raise KeyError(f"Unknown vulnerability rule: {rule_id}")
    return definition


def all_vulnerabilities() -> list[VulnerabilityDefinition]:
    return [v for _, v in sorted(_known_vulnerabilities().items())]


def list_vulnerability_ids() -> list[str]:
    return [v.id for v in all_vulnerabilities()]


# ---------------------------------------------------------------------------
# Firestore provider (set DSC_VULN_PROVIDER=local to disable)
# ---------------------------------------------------------------------------
import os as _os
import logging as _logging
import threading as _threading

_PROVIDER = _os.environ.get("DSC_VULN_PROVIDER", "firestore")

# Module-level Firestore-backed store (populated only when provider=firestore)
_firestore_catalog: dict[str, VulnerabilityDefinition] = {}
_catalog_lock = _threading.Lock()


def _load_from_firestore() -> dict[str, VulnerabilityDefinition]:
	"""Load CWE rules from Firestore, returning empty dict on failure."""
	from dsc.vulnerabilities.firestore_provider import fetch_cwe_rules  # type: ignore[import]
	rows = fetch_cwe_rules()
	if not rows:
		return {}

	_log = _logging.getLogger(__name__)
	result: dict[str, VulnerabilityDefinition] = {}
	for row in rows:
		try:
			raw_severity = row.get("severity_default", "MEDIUM")
			raw_hints = row.get("detection_hints")
			hints: dict[str, Any] = dict(raw_hints) if isinstance(raw_hints, dict) else {}
			rule = VulnerabilityDefinition(
				id=row["id"],
				cwe=row.get("cwe", ""),
				name=row.get("name", ""),
				description=row.get("description", ""),
				severity_default=Severity.from_str(raw_severity),
				tags=tuple(row.get("tags", [])),
				languages=tuple(row.get("languages", [])),
				vulnerable_example=row.get("vulnerable_example", None),
				secure_example=row.get("secure_example", None),
				fix_suggestion=row.get("fix_suggestion", None),
				references=tuple(row.get("references", [])),
				detection_hints=hints,
			)
			result[rule.id] = rule
		except Exception as exc:
			_logging.getLogger(__name__).warning(
				"Skipping malformed Firestore cwe_rules doc %s (raw severity=%r): %s",
				row.get("id"), row.get("severity_default"), exc,
			)
	return result


def _reload_cwe_catalog() -> None:
	"""Reload CWE rules from Firestore and clear the LRU cache."""
	global _firestore_catalog
	_log = _logging.getLogger(__name__)
	loaded = _load_from_firestore()
	if loaded:
		# Validate: reject if loaded count < 50% of hardcoded count (partial/corrupt fetch)
		hardcoded_count = len(_original_known_vulnerabilities())
		if hardcoded_count and len(loaded) < hardcoded_count * 0.5:
			_log.warning(
				"Firestore returned only %d CWE rules (< 50%% of %d hardcoded); "
				"rejecting and keeping existing catalog",
				len(loaded), hardcoded_count,
			)
			return
		with _catalog_lock:
			_firestore_catalog = loaded
		# Clear the original LRU so _original_known_vulnerabilities re-evaluates on next call.
		_original_known_vulnerabilities.cache_clear()
		_log.info(
			"DSC CWE catalog reloaded from Firestore: %d rules", len(loaded)
		)
	# If loaded is empty, keep existing _firestore_catalog (fail-open)


if _PROVIDER == "firestore":
	_original_known_vulnerabilities = _known_vulnerabilities
	_fallback_logged = False
	_lazy_init_done = False

	def _ensure_firestore_loaded() -> None:
		"""Lazy-load from Firestore on first catalog access.

		Previous behavior was eager (blocking import time).  This defers
		the network round-trip until the catalog is actually needed,
		cutting ~3-8s from process startup for callers that may not scan.
		"""
		global _lazy_init_done
		if _lazy_init_done:
			return
		with _catalog_lock:
			if _lazy_init_done:
				return
			_lazy_init_done = True
		# Run outside lock (network I/O may be slow).
		_reload_cwe_catalog()
		# Start background refresh daemon for periodic re-fetches.
		from dsc.vulnerabilities._refresh import start_refresh_daemon
		start_refresh_daemon(_reload_cwe_catalog)

	def _known_vulnerabilities() -> dict[str, VulnerabilityDefinition]:  # type: ignore[misc]
		"""Firestore-first: proxy -> disk cache -> hardcoded fallback."""
		global _fallback_logged
		_ensure_firestore_loaded()
		with _catalog_lock:
			snapshot = _firestore_catalog
		if snapshot:
			_fallback_logged = False
			return snapshot
		# Emergency fallback -- Firestore and disk cache both unavailable
		if not _fallback_logged:
			_logging.getLogger(__name__).error(
				"DEGRADED: Firestore CWE catalog empty, falling back to %d hardcoded rules",
				len(_original_known_vulnerabilities()),
			)
			_fallback_logged = True
		return _original_known_vulnerabilities()

	def reset_vulnerability_cache() -> None:  # type: ignore[misc]
		_original_known_vulnerabilities.cache_clear()
