Repository navigation
Audit fixes: the remaining 9 HIGH findings (parsers, analysis, wiring) - #26
Open
Krishcalin wants to merge 3 commits into
Open
Krishcalin wants to merge 3 commits into
Krishcalin wants to merge 3 commits into
Conversation
…dit HIGH x4) - Check Point NAT direction (checkpoint/mgmt.py): a hide/source-NAT rule carries the built-in "Original" object as its translated destination, and a non-empty translated-destination was read as a destination translation — so every source NAT was misclassified as publishing an internal host, a fabricated exposure (FR-FW-04). Strip "Original" before deciding direction. - NSX mixed group typing (vmware/nsx.py): a group with static members AND a tag condition was typed a plain 'group', so its static members looked like the complete set and a rule using it silently excluded everything the tag matches. Any dynamic condition now types it 'dynamic-group' (externally resolved); the static members remain as a partial view. - Junos deactivation (juniper/junos.py): `| display set` — the profile's primary form — renders a deactivated statement as its own `deactivate <path>` line, not an `inactive:` prefix, and those were ignored, so deactivated services/policies/interfaces reported as live. to_set_statements now collects `deactivate` paths and marks any set under one inactive (subtree included). - Junos AAA secret (core/redaction.py): `secret "$9$..."` matched no redaction rule, so the RADIUS/TACACS shared secret reached the AAA-server provenance excerpt and flowed into findings/reports. Added a rule anchored on Junos's quoted-secret form, which does not half-fire on FortiOS `set secret ENC <unquoted>`. Each adds the regression test the audit noted was missing. Green: junos (49), checkpoint+cloud/sdn (148), silent-emptiness/parsers/aaa (378 across the touched suites). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…absent data (audit HIGH x3) - EOL product shadowing (vuln/eol.py): _eol_records filters only by vendor, so a vendor's several products versioned in lockstep (FortiOS 7.0 end-of-support, FortiAnalyzer 7.0 supported) both reached _best_cycle, which matched purely on the numeric cycle and let one product's lifecycle clear a real end-of-support finding on another. _best_cycle now restricts to records whose product aligns with the device's platform (containment either way, so `asa` matches `cisco_asa` and `FortiOS` matches `fortios`), falling back to all records when nothing aligns. - Discovery fingerprint vendor conflict (discovery/fingerprint.py): read_text let a later platform-bearing pattern overwrite an earlier vendor-only match, so a string naming two vendors returned one, discarded the other, and flagged NO conflict — and fingerprint() built a confident verdict from an ambiguous signal. A multi-vendor string now yields no vendor; a single-vendor string still takes its most specific platform. - AAA fabricated finding (aaa_correlation.py): a device in inventory but never collected (already counted as not-evaluated) fell through to the unregistered-device append, so a device nothing was collected from was reported as a HIGH local-only/unregistered finding. Guarded: an uncollected device is skipped from registration analysis. Each adds the regression test the audit noted was missing. Green: eol (26), discovery fingerprint + aaa correlation + eol (91 across the touched suites). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t HIGH x2) - KEV never notified for medium/low findings (integrations/triggers.py): scan() fetched new findings filtered to critical/high BEFORE the KEV promotion loop, so a finding for a CISA-KEV CVE scored medium/low (CVSS < 7, common) was excluded and EventKind.KEV_MATCHED was never emitted — the "being exploited right now" alert the KEV path exists to raise. The query now also fetches every VULN finding with a CVE so KEV promotion can reach it; non-KEV low-severity findings are dropped in the loop, not notified. - Retention never ran (services/jobs.py, services/schedules.py, workers/scheduler.py): JobType.RETENTION had an executor (_run_retention) but no creator, and the generic create() requires a device scope, so a retention job could not be made. Added JobService.create_retention (device-less, like create_notify), a RETENTION branch in ScheduleService._fire_one, and ScheduleService.ensure_system_schedules() which seeds a daily retention schedule (idempotent), called once at scheduler startup. Artefact retention (FR-ADM-01) and the abandoned-SSO-state sweep (FR-AUTH-04, an unauthenticated table that otherwise grows without bound) now run automatically. Adds test_triggers.py (KEV medium promoted to a critical KEV event; non-KEV medium not notified) and schedule tests (a due retention schedule fires a device-less job; the seed is idempotent). Green: triggers+notifications (24), schedules+retention (34). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audit fixes — the remaining 9 HIGH findings
Closes the last of the 23 highs from the 2026-09-30 adversarial audit (
docs/audit/2026-09-30-adversarial-audit.md). Basemain; independent of #22–#25. 9 fixes in three commits, each with the regression test the audit noted was missing.Parser fidelity (
fb116f5) — 4group, so its static members looked like the complete set. Any dynamic condition now types itdynamic-group(externally resolved).deactivate:| display setrenders deactivations as their owndeactivate <path>lines (notinactive:), which were ignored — deactivated services/policies reported live. Now collected and applied to the subtree.secret "$9$…"matched no redaction rule and reached provenance excerpts. Added a rule anchored on Junos's quoted form (no clash with FortiOSset secret ENC).Analysis correctness (
51f0925) — 3_best_cyclenow restricts to the device's product (normalised containment:asa↔cisco_asa,FortiOS↔fortios).Wiring (
643692b) — 2scan()filtered findings to critical/high before KEV promotion, so a medium/low KEV CVE never raisedKEV_MATCHED. It now fetches VULN-with-CVE findings so promotion can reach them; non-KEV low ones are dropped, not notified.JobType.RETENTIONhad an executor but no creator, and the genericcreate()needs a device scope. Addedcreate_retention(device-less), a schedule branch, andensure_system_schedules()seeding a daily retention schedule at scheduler startup. Artefact retention (FR-ADM-01) and the abandoned-SSO-state sweep (FR-AUTH-04, an unauthenticated unbounded-growth table) now run.Tests
Green across every touched suite: junos (49), checkpoint+cloud/sdn (148), eol (26), discovery-fingerprint+aaa (91), triggers+notifications (24), schedules+retention (34).
With this, all 23 HIGH audit findings are resolved (across #23, #24, #25, and this PR).
🤖 Generated with Claude Code