mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-21 14:09:27 +00:00
fix(census): stop hiding findings behind a question-outcome count, and correct the PHP record
PHP is not silent. Paid Memberships Pro establishes findings, including a true positive, and this project's own instrument is why it looked otherwise. The census harness ordered its verdict on completion before findings, so a family with eighteen findings and no completed question reported "asked but no question completed". Findings are now checked first: a question-outcome count is bookkeeping and cannot hide the thing being censused. NodeGoat and VAmPI were never affected, because they complete every question and their verdicts reached the findings check. The scan summary now also carries the total findings and the outcome status counts, so the two numbers can be seen disagreeing instead of one silently winning. The second mistake was mine rather than the harness's: only the 500-region runs had been looked at, which are the ones that time out. What PHP actually detects on PMPro. At 25 regions, 19 findings in seven minutes with no timeout; at 100 regions, 43 findings in twelve minutes with no timeout. Among them adminpages/ discountcodes.php:749, where sanitize_text_field($_REQUEST["s"]) reaches $wpdb->get_results($sqlQuery, OBJECT) through `$sqlQuery .= "WHERE code LIKE '%$s%' "` with no prepare. That is the class of CVE-2023-23488, which php.toml's own comment names as the reason those WordPress sanitizers are kept out of the sanitizer list. The prediction and the measurement agree. The precision cost beside it is measured too: output encoding reports eighteen findings at 25 regions and the three sampled are all properly escaped, two with esc_attr and one coerced with intval. Those escapers are absent from a sanitizer list that is flat across families, because none of them stops SQL injection. Keeping the injection finding costs this family its precision. The scale limit is roughly one to two seconds per question. 25 and 100 regions complete cleanly; 500 regions asks 2,526 questions, needs more than the 1,800-second ceiling and is killed. Four things are measured NOT to be the problem: the malformed-CPG bug (fixed in 4.0.625, verified on the real trigger file), the dataflow overlay (42 s on the full 637-file graph), the engine version (4.0.625 and 4.0.631 indistinguishable), and the bundled Stripe, Braintree and Twocheckout SDKs under includes/lib that the vendored list does not cover -- that was my hypothesis for the cost and the overlay measures 42 s with them and 37 s without, so it is refuted. What remains is bookkeeping, not detection: questions_completed is zero in every PHP run including the ones that find things, with cross_partition_semantics_unresolved and partition_file_census_incomplete present throughout. The admission policy reads those outcomes. 1,417 tests pass, eighteen skipped. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5
parent
99abe12062
commit
1f51c82b51
@@ -196,6 +196,16 @@ pinned that version throughout; it is verified today on the real trigger file, o
|
||||
failure take longer. The engine pin stays where it is, because the newer release measures the
|
||||
same here.
|
||||
|
||||
That runtime reading was itself incomplete, and the correction matters more than the reading.
|
||||
PHP is not silent: at 25 and 100 regions PMPro completes with no timeout at all and establishes
|
||||
19 and 43 findings, including a true-positive SQL injection at
|
||||
`adminpages/discountcodes.php:749` of exactly the class the PHP fact table predicted. It looked
|
||||
silent because the census harness ordered its verdict on question completion before findings,
|
||||
and because only the 500-region runs had been examined. The harness is fixed. What remains is a
|
||||
scale limit of roughly one to two seconds per question, and one real gap that is bookkeeping
|
||||
rather than detection: no PHP question is ever marked completed, even in the runs that find
|
||||
things.
|
||||
|
||||
Closing the second gap surfaced four defects, three of which were false positives it would
|
||||
otherwise have shipped: a permissive-value set shared across settings whose booleans have
|
||||
opposite polarity, a dotted setting matched on its trailing segment alone, a flow query asked of
|
||||
@@ -211,4 +221,5 @@ Evidence: [family detection census](../../../benchmarks/measurements/2026-09-19-
|
||||
[collection read obligation](../../../benchmarks/measurements/2026-09-20-collection-read-obligation.json),
|
||||
[sibling scope and identity](../../../benchmarks/measurements/2026-09-20-sibling-scope-and-identity.json),
|
||||
[every permissive setting](../../../benchmarks/measurements/2026-09-20-every-permissive-setting.json),
|
||||
[PHP runtime after the graph fix](../../../benchmarks/measurements/2026-09-20-php-runtime-after-graph-fix.json).
|
||||
[PHP runtime after the graph fix](../../../benchmarks/measurements/2026-09-20-php-runtime-after-graph-fix.json),
|
||||
[PHP detection corrected](../../../benchmarks/measurements/2026-09-20-php-detection-corrected.json).
|
||||
|
||||
Reference in New Issue
Block a user