Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 5 additions & 2 deletions src/security_scanner/cli/commands/vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 7 additions & 2 deletions src/security_scanner/runtime/vulnerability_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Comment on lines +54 to 59

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

SemgrepCompatibleRunner는 항상 --metrics=off를 강제하므로, semgrep_config"auto"로 설정되면 무조건 실패하게 됩니다. 사용자가 CLI나 API를 통해 명시적으로 "auto"를 전달할 경우, 불필요한 서브프로세스 실행 없이 즉시 에러를 발생시키도록 __post_init__에서 방어적 유효성 검증(defensive validation)을 추가하는 것이 좋습니다.

Suggested change
# 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"
# 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"
def __post_init__(self) -> None:
if self.semgrep_config == "auto":
raise ValueError(
"semgrep_config='auto' is incompatible with --metrics=off"
)


Expand Down Expand Up @@ -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"
Comment on lines +149 to 153

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

동일하게 CatalogScanRequest에서도 semgrep_config"auto"로 설정되는 것을 방지하기 위해 __post_init__ 유효성 검증을 추가하는 것이 안전합니다.

    # "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"

    def __post_init__(self) -> None:
        if self.semgrep_config == "auto":
            raise ValueError(
                "semgrep_config='auto' is incompatible with --metrics=off"
            )


Expand Down
45 changes: 45 additions & 0 deletions tests/test_vuln_semgrep_config_metrics.py
Original file line number Diff line number Diff line change
@@ -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"
Comment on lines +33 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

ScanVulnerabilityRequestCatalogScanRequest에 추가된 "auto" 설정 방지 유효성 검증이 올바르게 작동하는지 확인하는 회귀 테스트를 추가하는 것이 좋습니다.

Suggested change
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_scan_request_default_config_is_not_auto():
assert ScanVulnerabilityRequest(root=".", output_path="o").semgrep_config != "auto"
def test_scan_request_rejects_auto_config():
import pytest
with pytest.raises(ValueError, match="semgrep_config='auto' is incompatible"):
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_catalog_request_rejects_auto_config():
import pytest
with pytest.raises(ValueError, match="semgrep_config='auto' is incompatible"):
CatalogScanRequest(artifact_dir="a", scan_run_id="r", 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
Loading