Problem
zerg.security.scanner (scanner.py, 679 lines) is 100% regex-based. It matches text patterns from PATTERN_REGISTRY (patterns.py, 1017 lines) but has no AST awareness, no taint tracking, and high false positive rates (matches patterns in comments, strings, docstrings). It cannot detect context-dependent vulnerabilities like SQL injection via variable flow or auth bypass through logic errors.
Meanwhile, semgrep provides AST-aware analysis, taint tracking (Pro), 30+ language support, and ships a p/bandit ruleset that covers ~95% of bandit's Python checks — making a separate bandit install redundant.
Proposed Solution
Integrate semgrep into run_security_scan() as an additional scan backend alongside existing regex patterns and CVE scanning. The scanner becomes an orchestrator:
run_security_scan(files)
→ 1. Semgrep scan (AST-aware, p/security-audit + p/bandit rulesets)
→ 2. Regex pattern scan (PATTERN_REGISTRY — catches custom patterns semgrep doesn't cover)
→ 3. CVE dependency scan (osv.dev API via cve.py)
→ Merge all findings into unified SecurityResult
Key Design Decisions
- Semgrep is the primary SAST tool — no bandit (semgrep's p/bandit covers it)
- Regex patterns retained as supplementary — they catch ZERG-specific patterns and custom secret formats
- Graceful degradation — if semgrep not installed, scanner falls back to regex-only with a warning
- SARIF output — semgrep natively outputs SARIF, enabling GitHub Security tab integration
Files to Modify
| File |
Change |
zerg/security/scanner.py |
Add _run_semgrep() backend, integrate into run_security_scan() |
zerg/security/__init__.py |
Export new scan backends |
zerg/security/patterns.py |
Add semgrep_rule_id field to SecurityPattern for dedup with semgrep findings |
tests/unit/test_security_engine.py |
Test semgrep integration, fallback behavior |
tests/integration/test_security_scan.py |
End-to-end scan with semgrep installed |
Acceptance Criteria
Depends On
Blocks
Problem
zerg.security.scanner(scanner.py, 679 lines) is 100% regex-based. It matches text patterns fromPATTERN_REGISTRY(patterns.py, 1017 lines) but has no AST awareness, no taint tracking, and high false positive rates (matches patterns in comments, strings, docstrings). It cannot detect context-dependent vulnerabilities like SQL injection via variable flow or auth bypass through logic errors.Meanwhile, semgrep provides AST-aware analysis, taint tracking (Pro), 30+ language support, and ships a
p/banditruleset that covers ~95% of bandit's Python checks — making a separate bandit install redundant.Proposed Solution
Integrate semgrep into
run_security_scan()as an additional scan backend alongside existing regex patterns and CVE scanning. The scanner becomes an orchestrator:Key Design Decisions
Files to Modify
zerg/security/scanner.py_run_semgrep()backend, integrate intorun_security_scan()zerg/security/__init__.pyzerg/security/patterns.pysemgrep_rule_idfield toSecurityPatternfor dedup with semgrep findingstests/unit/test_security_engine.pytests/integration/test_security_scan.pyAcceptance Criteria
run_security_scan()calls semgrep when availableSecurityResultwith CWE mappings.zerg/config.yamlDepends On
Blocks