Skip to content

feat(detection): Phase B recall hardening — fix comment-stripping + add coverage (recall 0.42→0.86)#35

Merged
rennf93 merged 18 commits into
masterfrom
feat/phase-b-recall
Jun 26, 2026
Merged

feat(detection): Phase B recall hardening — fix comment-stripping + add coverage (recall 0.42→0.86)#35
rennf93 merged 18 commits into
masterfrom
feat/phase-b-recall

Conversation

@rennf93

@rennf93 rennf93 commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Stacks on #34 (base = feat/attack-campaign). Fast-forward, no conflict. Retarget to master after #33/#34 land.

Remediates the gaps the attack-sim harness + campaign measured. Pure recall pass — false positives held flat (the SELECT-in-prose FP is deferred to a separate precision pass).

Result (harness)

  • detection_rate: 0.421 → 0.857
  • fp_rate: 0.125 → 0.125 (ratchet-enforced; the recall additions did not worsen false positives)
  • Per class: sqli 0.98, nosql 0.92, ssrf/xss/path 0.95, ldap 0.97, cmd 0.86, template 0.45.

What changed (each async + hand-mirrored to guard_core/sync/, TDD with a detection test + a benign near-miss)

  1. Comment-stripping fixContentPreprocessor no longer merges SELECT/**/FROMSELECTFROM; preserves MySQL /*!…*/ conditional comments; word-glued comment injection (SEL/**/ECT) is now a detection signal. Quote-flanked comments still strip correctly (1'/**/OR1' OR).
  2. SQLi — DDL/stacked (DROP/TRUNCATE/ALTER, INSERT/UPDATE/DELETE), ORDER BY enumeration, and a '1'='1 tautology pattern (also catches the pre-existing boolean-SQLi miss).
  3. NoSQL — JSON-quoted operators ("$gt", "$ne", …).
  4. SSTI — ERB <%= %> and expression-bearing ${…} (method call / @class@ / arithmetic).
  5. cmd-injection — bare-separator + reverse-shell (netcat/-e, /dev/tcp) patterns; fullwidth separators (;|&) normalized.
  6. New categoriesproto_pollution and code_injection, fully registered (contexts, ALL_DETECTION_CATEGORIES, CATEGORY_CONTEXT_MAP, catalog tests incl. the sync mirror).
  7. Ratchet baseline re-recorded; long pattern/test lines wrapped to satisfy ruff check E501/I001.

Verification

340 tests pass (incl. the catalog test + sync mirror + the attack-sim ratchet). ruff check + ruff format --check clean; vulture clean. Patterns are ReDoS-conscious (no nested quantifiers); async/sync handler pattern lists are byte-identical.

Deferred (noted, not in this PR)

  • template recall (0.45) — encoded mutation variants of ${…}/{{…}} still evade.
  • #-bearing OGNL (${#ctx…}) is truncated by the # SQL-line-comment stripper — a preprocessor/precision issue.
  • The prose_sql_keywords false positive (0.67) — the dedicated precision pass (B3).

Test-only + detection-code edits; no API/route changes. Pre-existing sync-mirror --check CI may be red, unrelated.

@github-actions github-actions Bot added area: detection-engine Touches guard_core/detection_engine/ area: handlers Touches guard_core/handlers/ area: sync Touches guard_core/sync/ (sync mirror generated by unasync) tests Test suite changes labels Jun 26, 2026
Base automatically changed from feat/attack-campaign to master June 26, 2026 01:28
@rennf93 rennf93 self-assigned this Jun 26, 2026
@rennf93
rennf93 merged commit c33407b into master Jun 26, 2026
4 of 10 checks passed
@rennf93
rennf93 deleted the feat/phase-b-recall branch June 26, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: detection-engine Touches guard_core/detection_engine/ area: handlers Touches guard_core/handlers/ area: sync Touches guard_core/sync/ (sync mirror generated by unasync) tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant