Skip to content

Commit 0d7a83f

Browse files
committed
fix(sdk): add universal post-scan exclude filter in engine
Only bandit read the exclude config — OSV, OpenGrep, and other scanners ignored it, still reporting test fixture findings. New approach: the engine applies exclude filtering AFTER parsing, regardless of whether the tool supports it natively. Any finding whose location contains an excluded path is dropped. This is scanner-agnostic — works for all scanners universally. The tool still scans everything (catches real issues in all paths), but excluded findings are removed before reporting.
1 parent a81d32c commit 0d7a83f

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

argus/core/engine.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ def run(
6666

6767
try:
6868
result = self._run_scanner(scanner, scan_path, config_dict)
69+
70+
# Filter out findings from excluded paths
71+
exclude = config_dict.get("exclude", "")
72+
if exclude and result.findings:
73+
before = len(result.findings)
74+
result = self._filter_excluded(result, exclude)
75+
filtered = before - len(result.findings)
76+
if filtered:
77+
logger.debug(
78+
"Filtered %d finding(s) from excluded paths for '%s'",
79+
filtered,
80+
name,
81+
)
82+
6983
elapsed = int((time.monotonic() - start) * 1000)
7084
logger.info(
7185
"Scanner '%s' completed in %dms: %d finding(s)",
@@ -418,6 +432,34 @@ def _resolve_scanner_names(self, requested: list[str] | None) -> list[str]:
418432
if self.config.get_scanner_config(name).enabled
419433
]
420434

435+
@staticmethod
436+
def _filter_excluded(result: ScanResult, exclude: str) -> ScanResult:
437+
"""Remove findings whose location matches an excluded path.
438+
439+
This is the universal exclude mechanism — works for all scanners
440+
regardless of whether the tool itself supports path exclusion.
441+
Applied post-parse so the scanner still runs on everything, but
442+
excluded findings are dropped before reporting.
443+
"""
444+
exclude_parts = [p.strip() for p in exclude.split(",") if p.strip()]
445+
if not exclude_parts:
446+
return result
447+
448+
filtered = []
449+
for finding in result.findings:
450+
location = finding.location or ""
451+
if any(exc in location for exc in exclude_parts):
452+
continue
453+
filtered.append(finding)
454+
455+
return ScanResult(
456+
scanner=result.scanner,
457+
findings=filtered,
458+
raw_report=result.raw_report,
459+
sarif_report=result.sarif_report,
460+
metadata=result.metadata,
461+
)
462+
421463
@staticmethod
422464
def _build_scanner_config_dict(scanner_config) -> dict:
423465
"""Flatten a ScannerConfig into a plain dict for the scanner."""

0 commit comments

Comments
 (0)