mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-21 14:09:27 +00:00
docs(specs): WordPress flaw classes, the corpus insight, and an IR brief
Three directions recorded, each grounded in what this session measured. **WordPress by flaw class, not by plugin** (tasks 5.8, 5.9). One plugin is a checkout; a class is a claim. WordPress's recurring shapes are narrow and each maps to a family that already exists -- unauthenticated wp_ajax_nopriv reaching $wpdb, a missing capability check, unescaped output, arbitrary file operations. Two of the four are blocked on gaps this session found: access control cannot be asked at all because PHP has no obligation facts (5.9), and unescaped output is blocked on the flat sanitizer list (5.6). The observable is a class-by-class table across several plugins saying found, missed, or out of scope -- a single found CVE is not the artifact worth teaching from. **Why a corpus of benchmarks is not enough on its own**, written into overview.md as the finding it is rather than an opinion. Twelve engine defects in one session against three real repositories, and the three gates stayed byte-identical through every fix. A gate that does not move is a corpus that could not see the bug. The reason is structural: a pair is a labelled function with a declared family and a known answer, so it cannot exercise which region to look at, what to spend, whether a capability is reachable, whether two entry points share a sink, whether the question fits in an argv slot, or whether a flow crosses a module. Three of the twelve were quiet failures where the tool reported clean and every honesty counter agreed -- which a benchmark score cannot express, because the score is computed from the verdicts that exist. The corpus is the holdout that stops per-repository tuning, and the wrong instrument for finding out whether the tool works. **ir-consolidation** (brief, unapproved) separates two questions the IR suggestion contains, which have opposite answers. The SOURCE IR is already carried rather than about to be added: semantic/ is 3218 lines, 16% of the codebase, measured at 2.2% entailment against the CPG's 41.3% and still running as a proposer -- and Vine and P-Code are binary IRs, so the work there is subtraction. The MISSING abstraction is C arithmetic, and there GhidraPAL's three-valued-logic abstract interpreter over Ghidra P-Code is exactly the right shape: "can this index exceed this allocation" is a value question, which is what a bit-level TVL domain answers and what every libpng overflow needs. Vine is dormant since 2009 and is not the candidate. The constraint is recorded as an ordering: question 1 lands before question 2 starts, or adopting an IR makes the growth problem worse. And the cost that matters is not lines but the number of things that can silently return nothing -- this session found three such in a single PHP scan, and a binary pipeline adds a build, a lifter and a domain, each able to produce an empty result that looks like a clean one. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
co-authored by
Claude Opus 5
parent
8579c10e7c
commit
db273dde53
@@ -0,0 +1,68 @@
|
||||
# Brief: ir-consolidation — stop maintaining an IR we did not need, and adopt one we do
|
||||
|
||||
**Status:** brief only, unapproved.
|
||||
|
||||
## Why now
|
||||
|
||||
> "we should make sure our code base here doesn't explode. for example we have a custom IR. maybe vine
|
||||
> (berkely) or another existing IR (rolf rolles had one) ... I know Ghidra has one we could steal"
|
||||
|
||||
Two different questions live inside that, and they have opposite answers. Keeping them apart is most of the
|
||||
value of this brief.
|
||||
|
||||
## Question 1 — the source IR we already replaced and never retired
|
||||
|
||||
`semantic/` is **3,218 lines, 16% of the codebase**: a hand-written IR (`ir.py`, `cst.py`) and a flat taint
|
||||
engine (`taint.py`), plus the overlay that runs them. `model-grounded-detection` measured that IR against
|
||||
Joern's CPG and the result was decisive — **2.2% entailment against 41.3%** — which is why the CPG was
|
||||
adopted for the model layer. The flat IR was never removed, and still runs as a proposer in every scan.
|
||||
|
||||
So the outgrowth is not something we are about to add. It is something already carried.
|
||||
|
||||
**Vine and P-Code do not help here.** Both are *binary* IRs — Vine lifts executables (BitBlaze, UC Berkeley,
|
||||
GPL-2.0, last significant activity 2009), and P-Code lifts machine code. Our source languages are Python,
|
||||
PHP, JavaScript and Java, and the source IR we should adopt is the one we already have. The work is
|
||||
subtraction, not substitution:
|
||||
|
||||
- Can the CPG serve the overlay's job at equal or better recall?
|
||||
- What does deleting `semantic/`'s IR and taint cost, measured on the pair corpus and both repositories?
|
||||
- What has to stay? `obligations/` reads the same facts and is a different analysis.
|
||||
|
||||
A candidate ~1,000-line deletion with a number attached, which is the only kind worth doing.
|
||||
|
||||
## Question 2 — the abstraction we are missing, where an existing IR is exactly right
|
||||
|
||||
`c/memory` has produced **zero true positives** and three distinct classes of false one. The reason is
|
||||
structural and now stated in the report (Req 5.6): it models unbounded string CALLS, while real C overflows
|
||||
are *arithmetic* — an index, a pointer offset, a `memcpy` whose size is computed. Every one of libpng's is,
|
||||
and its library code never calls a modelled string API at all.
|
||||
|
||||
"Can this expression exceed this allocation" is a value question, not a reachability one. **Rolf Rolles'
|
||||
GhidraPAL carries a three-valued-logic abstract interpreter over Ghidra P-Code** — each bit definite 0,
|
||||
definite 1, or unknown, with abstract transformers for `INT_ADD`, `INT_MULT`, `INT_AND`, the comparisons —
|
||||
validated against concrete execution in its own tests. That is precisely the shape of analysis the C family
|
||||
lacks, and it exists.
|
||||
|
||||
It is also the honest answer to a decision this project already took. `model-grounded-detection` chose
|
||||
abstract interpretation over SMT, and chose to build the model from code because execution cannot be
|
||||
assumed. A bit-level abstract interpreter over P-Code is *still abstract interpretation* and still static —
|
||||
what changes is the artifact: it needs a **built** library rather than its source.
|
||||
|
||||
## What this brief must decide
|
||||
|
||||
1. Whether the source-IR subtraction is safe, measured rather than assumed.
|
||||
2. Whether the C arithmetic class is worth a second pipeline at all, or whether `c/memory` stays scoped to
|
||||
string misuse and says so — which is where task 2.16 left it, deliberately.
|
||||
3. If it is worth it: P-Code with a TVL domain, adapting GhidraPAL's transformers, versus writing one. Vine
|
||||
is dormant since 2009 and is not the candidate; Ghidra is maintained and P-Code has tooling.
|
||||
4. What a second pipeline costs in the one currency this project has been strict about — **not lines, but
|
||||
the number of things that can silently return nothing.** This session found three separate quiet failures
|
||||
in one PHP scan. A binary pipeline adds a build step, a lifter, and a domain, each of which can produce
|
||||
an empty result that looks like a clean one.
|
||||
|
||||
## The constraint that governs it
|
||||
|
||||
Nothing here may grow the codebase without a measurement that justifies it, and the module audit
|
||||
(`benchmarks/measurements/2026-09-08-module-audit.json`, currently 97 modules with no orphans) is the
|
||||
instrument. A brief that ends in "adopt P-Code" and 3,000 new lines while `semantic/` still carries 3,218
|
||||
has made the problem worse, not better. **Question 1 should land before Question 2 starts.**
|
||||
Reference in New Issue
Block a user