Skip to content

fix(assail): null-check-aware UncheckedAllocation + precise eval detectors#134

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/assail-precision-null-check-eval
Jun 24, 2026
Merged

fix(assail): null-check-aware UncheckedAllocation + precise eval detectors#134
hyperpolymath merged 1 commit into
mainfrom
fix/assail-precision-null-check-eval

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Three precision fixes to the assail analyzers that produced false positives across the estate — found while triaging hyperpolymath/proven#68 and JoshuaJewell/paint-type#86, and the root cause of why genuine fixes didn't clear. All conservative: no new false negatives.

1. UncheckedAllocation is now actually "unchecked"-aware (C)

The detector flagged every malloc(...) regardless of a NULL check, and emitted a line-less, file-level finding. Now it:

  • scans per line and skips a malloc whose result is NULL-checked within a short window (if (p == NULL), if (!p), nullptr);
  • attaches a line number — which also lets an inline // panic-attack: accepted marker suppress a reviewed site (previously impossible: marker suppression is line-gated).

This is precisely why a real null-check fix (proven stubs.c) never cleared before.

2. eval() detectors are word-boundary aware (JS / Python)

contains("eval(") matched FFI symbol names like proven_calculator_eval(. Now \beval\s*\( (and \b(?:eval|exec)\s*\( for Python). Genuine eval( still flagged.

3. Shell eval no longer matches the --eval CLI flag

contains("eval ") matched --eval. Now the eval builtin is matched only in statement position — (?m)(?:^|[\s;&|(])eval[ \t]. --eval/-eval no longer flagged; the real shell eval builtin still is.

Verification

  • 4 new tests (tests/analyzer_tests.rs): null-checked malloc skipped; genuinely-unchecked still flagged; shell --eval flag not flagged but builtin is; FFI *_eval( not flagged but real eval() is.
  • Full analyzer suite 17/17 green, zero warnings.
  • End-to-end: rebuilt 2.5.5 and re-scanned —
    • proven: 1 → 0 active Critical/High (stubs.c clears; the genuine fix finally registers).
    • paint-type: 36 → 35 (the gossamer --eval benchmark FP clears; the 3 irreducible believe_me axioms + 32 genuinely-unsafe vendored Zig FFI correctly remain — no over-suppression).

Refs #32, hyperpolymath/proven#68.

🤖 Generated with Claude Code

…detectors

Three precision fixes to the C/JS/Python/Shell analyzers that were producing
false positives across the estate (surfaced triaging hyperpolymath/proven#68
and JoshuaJewell/paint-type#86):

1. UncheckedAllocation (C): the detector named "Unchecked" flagged EVERY
   `malloc(...)` regardless of a following NULL check, and emitted a line-less,
   file-level finding. It now scans per line, skips a malloc whose result is
   NULL-checked within a short window (`if (p == NULL)`, `if (!p)`, nullptr),
   and attaches a line number. Net effect: genuinely-guarded allocations stop
   firing, genuinely-unchecked ones still fire (new test), and the line number
   lets an inline `// panic-attack: accepted` marker suppress a reviewed site.
   This is why a real null-check fix (proven stubs.c) previously did not clear.

2. DynamicCodeExecution (JS/Python): `contains("eval(")` matched FFI symbol
   names like `proven_calculator_eval(`. Now word-boundary `\beval\s*\(`
   (and `\b(?:eval|exec)\s*\(` for Python) — genuine `eval(` still flagged.

3. CommandInjection (Shell): `contains("eval ")` matched the `--eval` CLI flag.
   Now matches the eval builtin only in statement position
   (`(?m)(?:^|[\s;&|(])eval[ \t]`) — `--eval`/`-eval` no longer flagged, the
   real shell eval builtin still is.

All conservative (no new false negatives): a site is only treated as
checked/benign on a clear signal. Verified end-to-end — proven: 1 active
Critical/High -> 0 (stubs.c clears); paint-type: 36 -> 35 (the gossamer
`--eval` benchmark FP clears; genuinely-unsafe vendored FFI + the irreducible
believe_me axiom correctly remain). 4 new tests; full analyzer suite green
(17/17); zero warnings.

Refs #32, hyperpolymath/proven#68.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 34 issues detected

Severity Count
🔴 Critical 1
🟠 High 12
🟡 Medium 21

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "expect() in hot path (2 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/panic-attack/panic-attack/src/attestation/chain.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unsafe block -- requires SAFETY comment (1 occurrences, CWE-676)",
    "type": "unsafe_block",
    "file": "/home/runner/work/panic-attack/panic-attack/src/jit_context.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "mem::transmute bypasses type safety with unchecked bit reinterpretation (12 occurrences, CWE-704)",
    "type": "transmute",
    "file": "/home/runner/work/panic-attack/panic-attack/src/jit_context.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "expect() in hot path (4 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/panic-attack/panic-attack/src/assail/analyzer.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (1 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/panic-attack/panic-attack/src/query/mod.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (4 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "expect() in hot path (2 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "expect() in hot path (1 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/panic-attack/panic-attack/examples/attack_harness.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (9 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/panic-attack/panic-attack/examples/vulnerable_program.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 60d9219 into main Jun 24, 2026
31 of 32 checks passed
@hyperpolymath hyperpolymath deleted the fix/assail-precision-null-check-eval branch June 24, 2026 08:40
hyperpolymath added a commit that referenced this pull request Jun 29, 2026
Documentation follow-up to #134 (the detector precision fix), which
merged before these docs were added.

- **Human**: `CHANGELOG.md` `[Unreleased]` → "Fixed — assail detector
precision" entry.
- **Machine**: `.machine_readable/6a2/STATE.a2ml` →
`[session-2026-06-24]` block + `last-updated` bump.

Records the null-check-aware `UncheckedAllocation`, word-boundary
`eval(`, and statement-position shell `eval` fixes, with the verified
end-to-end results (proven 1→0, paint-type 36→35). Docs-only.

Refs #32.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant