Skip to content

Engine: multi-file taint / control-flow conditions (the dataflow ceiling) #87

Description

@noeljackson

Why

The recall agent (#61) returns `needs-engine-feature` for any FN class that can't be expressed in the current matcher schema. The Codex comparison in #79 showed this is the actual recall ceiling: many real bugs span multiple files (e.g., "this `exec` is reachable from this HTTP handler that doesn't authenticate users"), or hinge on control-flow conditions ("missing return after the validation rejects bad input").

Regex + AST per-file matchers cannot reach these. We have an honest ceiling.

What this issue tracks

Two related engine extensions, scoped together because they share infrastructure:

  1. Multi-file taint pre-filter (across-file). Today's `require_taint_within` (PR Scanner: lightweight taint pre-filter (closes #26) #68) is per-file. Extension: build an import graph (or shallow call graph) at scan time, propagate taint markers across imports, allow matchers to require "this candidate is reachable from a tainted source via at most N hops."

  2. Control-flow conditions. Matchers that fire on "function body where call X is not preceded by call Y" — e.g. "`r.URL.Query` reaches a sink without a sanitiser call in between." Requires reading the AST + simple intra-procedural reachability, not full dataflow.

Implementation notes

  • Both can be expressed as new `MatcherDef` fields: `require_taint_within_module` (graph hops) and `negative_query` (AST query that must NOT match in the function body).
  • Engine work lives in `internal/scanner/` and `internal/scanner/ast/` — keep it Go-pure, no CGO.
  • The skeptic + AI investigation phase still catches everything the engine misses. This work is about pulling recall into the matcher layer so we get cheap candidates instead of expensive AI calls.

Out of scope

Acceptance

  • An RFC under `docs/rfcs/` proposing the two field additions.
  • Implementation behind a feature flag (`engine.experimental = true` in `MatcherDef`).
  • At least 3 bench tasks where the new fields demonstrably catch FNs that today's matcher engine misses.

Why now

Until this lands, the recall ceiling on languages with strong-tier matcher packs (TS/Python/Go/Ruby) is what regex+AST can express. Everything else costs an AI call per candidate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions