mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
fix(cpg): single-query path drops params the script does not declare
taint.request_params emits guards/fixedOrigin/originAnchors/quotedSanitizers/
fieldParameterSources, which taint.sc reads from per-request JSON in its BATCH
branch but does NOT declare on `@main def exec` and does NOT consume in its
single-request branch (it defaults them). The single-query path passed them as
`--param guards=...` (disposable) or named args (session), so joern errored
`Unknown arguments` and every cpg.run("taint", ...) failed -- a silent zero of
the shape AGENTS.md warns about. scan_region->taint_verdict->_usable_flows and
the pair-path verdict()/verdicts() were dead; the push/scan batch route was
unaffected (it carries the extras as JSON the script parses itself).
Fix: parse the script's `@main def exec(...)` signature once (_declared_exec_params
+ memoised _declared_params) and, in query(), filter params to the declared set
before building either route. Faithful, not lossy -- the single-request branch
could never use those 5 fields. No-op for config/dominance (their request_params
emit only declared params; verified). Only taint sheds the 5 extras.
Verified end-to-end on banks (patched backend in the replay image): single-query
path now runs; baseline 0 findings, annotated search 2 path/model_entailed
findings (prompt->write_text). Regression test asserts no undeclared param
reaches the command line and the query parses, with a fake runner (no Joern).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8f7fc4ae83
commit
a024656da0
+23
-1
@@ -1,6 +1,28 @@
|
||||
# BUG: `taint.sc` single-query path broken by exec-signature skew
|
||||
|
||||
Filed: 2026-10-12 · Repo HEAD at filing: `7ab5c2a` · Severity: **high (silent zero)** · Status: OPEN
|
||||
Filed: 2026-10-12 · Repo HEAD at filing: `7ab5c2a` · Severity: **high (silent zero)** · Status: **FIXED (2026-10-12)**
|
||||
|
||||
## Resolution (2026-10-12)
|
||||
|
||||
Fixed via **option 1** (filter params to the declared signature) in `src/openultrasast/cpg/backend.py`:
|
||||
|
||||
- New `_declared_exec_params(source)` parses the `@main def exec(...)` parameter names from a shipped script
|
||||
(brace-aware, tolerant of an unfindable signature → empty set → "do not filter").
|
||||
- New memoised `JoernBackend._declared_params(query)` reads+caches a script's declared names.
|
||||
- `JoernBackend.query()` now drops any param the script does not declare before building the `--param` list
|
||||
(disposable route) and the in-session named-arg call (session route). This is faithful, not lossy: the
|
||||
single-request branch of `taint.sc` (line 1542) calls `rowsFor(...)` with top-level params only and lets
|
||||
`fixedOrigin`/`originAnchors`/`quotedSanitizers`/`guards`/`fieldParameterSources` default — it never could
|
||||
consume them. The batch path keeps carrying them as JSON the script parses itself.
|
||||
- No-op for `config`/`dominance`: their own `request_params` emit only params their `.sc` declares (verified),
|
||||
so nothing is dropped. Only `taint` sheds the 5 extras.
|
||||
|
||||
**Verified end-to-end** (patched backend mounted into the replay image, single-query path on banks): the
|
||||
queries now RUN (no `cpg query taint failed`); baseline = 0 findings, fixed search (annotation) = 2 scored
|
||||
`path`/`model_entailed` findings (`from_prompt_path` → `prompt_file.write_text(prompt.raw)` L45; `_scan` →
|
||||
`self._index_path.write_text(...)` L155). Regression test:
|
||||
`tests/test_cpg_backend.py::test_a_single_query_passes_only_params_the_script_declares` (fake runner, no Joern
|
||||
— asserts the 5 undeclared params never reach the command line and the query parses).
|
||||
|
||||
## Summary
|
||||
|
||||
|
||||
Reference in New Issue
Block a user