Skip to content

feat(whitebox): code-graph taint engine + graph-grounded AI triage - #164

Merged
dmdhrumilmistry merged 2 commits into
devfrom
feat/code-graph-taint-engine
Oct 20, 2026
Merged

dmdhrumilmistry merged 2 commits into
devfrom
feat/code-graph-taint-engine

Conversation

@dmdhrumilmistry

Copy link
Copy Markdown
Collaborator

Summary

Replaces the semgrep wrapper as the white-box core with a code property graph + interprocedural taint engine (whitebox/offat_wb/cpg/), and builds the AI layer on top of the proven data-flow paths instead of code snippets.

Engine

  • Graph: networkx MultiDiGraph with functions, params, versioned locals, self fields, call sites, args, returns and sources. Edges are flow (with per-class sanitizes), call-site-labelled call/ret, and calls. Exportable as JSON or GraphML (--graph-out).
  • Python (stdlib ast): Flask, FastAPI, Django/DRF, Tornado, aiohttp, Lambda, src/ layouts, nested functions, lambdas, and deferred calls (queue.enqueue(fn, x), fn.delay(x), Thread(target=fn), executors).
  • JS/TS (tree-sitter): Express routers, handler factories and wrappers (app.get(p, asyncHandler(login()))), require/import/export, callbacks, and TS destructured req.
  • Precision: matched call/return, reaching definitions (x = int(x) kills taint), per-class sanitizers, coerced params (int, <int:id>), BOLA with ownership-check suppression, whole-body-only mass assignment, and string-only sources excluded from NoSQL operator smuggling.
  • Findings: each carries the hop-by-hop path, its entry points and its HTTP route. SARIF now includes codeFlows.
  • Pattern hunter: still used for secrets, crypto and misconfig. Hits that duplicate a proven flow are dropped; unproven injection hits are demoted. semgrep is opt-in (--semgrep).
  • Graybox: reachability now comes from the graph.

AI

  • Batched triage receives the proven path, routes and authz context.
  • --agent N: a tool-use verifier (claude-opus-5-5) with read-only, repo-confined graph tools. It tries to refute first, then submits a verdict and a PoC request. Repo content is framed as untrusted data.
  • --infer-specs: computes the taint frontier and has the model label unknown sinks and sanitizers, which feed back via --specs.
  • Fixes the invalid default screen model ID (claude-haiku-5 → claude-haiku-5-5).

Benchmarks (graph engine only, no AI)

Target Time Result
fixture (Flask + FastAPI + Express) <1s 16/16 planted bugs found; 0 of 12 safe twins flagged
OWASP Juice Shop (4,260 functions) 6.3s 91 routes mapped; login and search SQLi, SSRF, redirect, 3× NoSQLi, eval/pug SSTI, basket IDOR, YAML deserialization
we45 Vulnerable-Flask-App 1.1s 4/5 taint-style bugs, 0 FP

See docs/ai-roadmap.md for the design and the roadmap.

Test plan

  • whitebox (16, including 12 new in test_cpg.py), graybox, triager, platform, reporter, bundle unit tests pass
  • Pipeline degrades to the pattern hunter without networkx and records why
  • Agent loop tested with a fake transport; not yet run against the live API

🤖 Generated with Claude Code

Replace the semgrep wrapper as the white-box core with a code property graph
(networkx) and an interprocedural source->sink taint search:

- Python frontend (stdlib ast): Flask, FastAPI, Django/DRF, Tornado, aiohttp,
  Lambda; src/ layouts; nested functions; deferred calls (RQ enqueue, celery
  .delay, threads, executors, BackgroundTasks); lambdas.
- JS/TS frontend (tree-sitter): Express routers incl. handler factories and
  wrappers, require/import/export, callbacks, TS destructured req.
- Matched call/return (call-site stack), versioned locals, per-class
  sanitizers, type-coerced params; BOLA candidates with ownership-check
  suppression; mass assignment on whole-body sources; ReDoS sinks.
- Findings carry the hop-by-hop path, entry points and routes; SARIF codeFlows.
- Pattern hits are fused: duplicates of proven flows dropped, unproven
  injection hits demoted and given graph reachability. semgrep is opt-in.
- Graybox reachability comes from the graph instead of graft/same-file.

AI on top of the graph:
- batched triage sees the proven path instead of a snippet;
- --agent N: tool-use verifier with read-only, repo-confined graph tools that
  submits a verdict plus a PoC request;
- --infer-specs: taint frontier + model-labelled sinks/sanitizers fed back
  via --specs.

Also fix the default screen model id (claude-haiku-5 -> claude-haiku-5-5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 19, 2026 19:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread whitebox/tests/test_cpg.py Fixed
- drop unused FrozenSet import (py_frontend) and _WHOLE_BODY constant (js_frontend)
- detect tree-sitter with importlib.util.find_spec instead of an unused import
- fixture: remove unused `fs` require; close the file in unused_helper with `with`
- test: locate the dead-code line in the fixture instead of hard-coding it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dmdhrumilmistry
dmdhrumilmistry merged commit d7a6c8e into dev Oct 20, 2026
14 checks passed
@dmdhrumilmistry
dmdhrumilmistry deleted the feat/code-graph-taint-engine branch October 21, 2026 10:17
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.

3 participants