diff --git a/deploy/systemd/user/security-scanner-personal-vuln-scan.service b/deploy/systemd/user/security-scanner-personal-vuln-scan.service index accaa69..b3fbe13 100644 --- a/deploy/systemd/user/security-scanner-personal-vuln-scan.service +++ b/deploy/systemd/user/security-scanner-personal-vuln-scan.service @@ -34,7 +34,7 @@ ExecStart=%h/.local/bin/uv run security-scanner scan-vuln \ --from-catalog \ --artifact-dir %h/.local/state/security-scanner/vuln-artifacts \ --semgrep-binary %h/.local/bin/semgrep \ - --semgrep-config auto \ + --semgrep-config p/default \ --timeout-seconds 1800 \ --path-policy redacted diff --git a/src/security_scanner/cli/commands/vulnerability.py b/src/security_scanner/cli/commands/vulnerability.py index f34a0e4..f5c8792 100644 --- a/src/security_scanner/cli/commands/vulnerability.py +++ b/src/security_scanner/cli/commands/vulnerability.py @@ -125,8 +125,11 @@ def register(subparsers) -> None: scan_parser.add_argument( "--semgrep-config", metavar="CONFIG", - default="auto", - help="Semgrep config value (default: auto).", + default="p/default", + help=( + "Semgrep config/ruleset (default: p/default). Note: 'auto' is " + "rejected because the runner forces --metrics=off for privacy." + ), ) scan_parser.add_argument( "--timeout-seconds", diff --git a/src/security_scanner/runtime/vulnerability_scan.py b/src/security_scanner/runtime/vulnerability_scan.py index 91fc169..aee688e 100644 --- a/src/security_scanner/runtime/vulnerability_scan.py +++ b/src/security_scanner/runtime/vulnerability_scan.py @@ -51,7 +51,10 @@ class ScanVulnerabilityRequest: output_path: str | Path sarif_output_path: str | Path | None = None semgrep_binary: str = "semgrep" - semgrep_config: str = "auto" + # NOT "auto": the runner forces --metrics=off for privacy, and semgrep + # rejects `auto` config when metrics are off ("Cannot create auto config + # when metrics are off"). A pinned registry pack runs without telemetry. + semgrep_config: str = "p/default" timeout_seconds: int = 300 path_policy: str = "redacted" @@ -143,7 +146,9 @@ class CatalogScanRequest: scan_run_id: str cache_root: str | Path | None = None semgrep_binary: str = "semgrep" - semgrep_config: str = "auto" + # "p/default", not "auto": auto is incompatible with the runner's forced + # --metrics=off (see ScanVulnerabilityRequest). + semgrep_config: str = "p/default" timeout_seconds: int = 1800 path_policy: str = "redacted" diff --git a/tests/test_vuln_semgrep_config_metrics.py b/tests/test_vuln_semgrep_config_metrics.py new file mode 100644 index 0000000..1d8f7df --- /dev/null +++ b/tests/test_vuln_semgrep_config_metrics.py @@ -0,0 +1,45 @@ +"""Regression guard: semgrep `auto` config is incompatible with `--metrics=off`. + +The Semgrep-compatible runner forces ``--metrics=off`` for privacy, and semgrep +rejects the ``auto`` config when metrics are off ("Cannot create auto config when +metrics are off"). So the vuln-scan defaults must NOT be ``auto`` — a live catalog +scan would fail every tick otherwise. This test pins that coupling. +""" + +from __future__ import annotations + +from pathlib import Path + +from security_scanner.runtime.vulnerability_scan import ( + CatalogScanRequest, + ScanVulnerabilityRequest, +) +from security_scanner.scanners.semgrep_compatible import SemgrepCompatibleRunner + +_UNIT = ( + Path(__file__).resolve().parents[1] + / "deploy" + / "systemd" + / "user" + / "security-scanner-personal-vuln-scan.service" +) + + +def test_runner_forces_metrics_off(): + cmd = SemgrepCompatibleRunner().build_command(Path("."), sarif_path="o.sarif") + assert "--metrics=off" in cmd + + +def test_scan_request_default_config_is_not_auto(): + assert ScanVulnerabilityRequest(root=".", output_path="o").semgrep_config != "auto" + + +def test_catalog_request_default_config_is_not_auto(): + req = CatalogScanRequest(artifact_dir="a", scan_run_id="r") + assert req.semgrep_config != "auto" + + +def test_vuln_scan_unit_does_not_use_auto_config(): + text = _UNIT.read_text(encoding="utf-8") + assert "--semgrep-config" in text + assert "--semgrep-config auto" not in text