contributor-scan 5.7, and it was the wrong question.
**The 117k-line pmpro CPG does not load.** Importing it throws in a
ForkJoinParallelCpgPassWithAccumulator during overlay application, so every
query against it returns nothing. It is not a call-graph question at all.
Isolated by running the ARBITER against two prebuilt CPGs rather than
writing a sixth ad-hoc Scala probe, four of which had already failed on my
own mistakes:
small wpdb CPG get_order_by_code -> 1 model_entailed
pmpro CPG getMemberOrderByCode -> 0
Both have their source and sink in ONE function, both were asked with
parameter sources and depth 3, same arbiter and same spec. The CPG is the
only difference.
That clears the facts, which is worth stating: `$wpdb` sinks work, the
parameter-source rule works, and a PHP parameter reaching `$wpdb->get_var`
through a concat is entailed. Whether php2cpg resolves `new X()` and
`$this->method()` is still unmeasured -- it cannot be measured on a CPG
that will not load -- and is recorded as 5.10 along with finding the size
boundary.
**And the defect underneath it, which is the fourth quiet failure found on
this one checkout.** `query_batch` returned `{}` for a failure and `{}` for
a genuine empty answer, so a caller could not tell "could not ask" from
"nothing found". Every query on this scan failed at load and it reported
500 regions examined, no findings, and no degradation: a vulnerable plugin,
clean.
A failed batch now returns None, unparseable output counts as a failure
rather than an empty answer, and the driver records a `query_failed`
degradation naming the kind and the request count.
This is the failure mode the rung ladder structurally cannot catch. Every
other honesty mechanism here labels a VERDICT -- suspicion,
regions_unjudged, regions_unasked, stated family limits -- and when no
verdict is produced there is nothing to label.
Gates byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
Reporting the result rather than the intention.
Paid Memberships Pro 2.9.7 with CVE-2023-23488 is pinned, verified in the
code, and scans cleanly: 637 files, 117k lines, 1577 regions, build 47s,
query 74s, 140s total, no degradations. **The CVE is not detected.**
Both ends are inside the budget -- the REST handler at position 290 as a
recognised entry point, the `$wpdb->get_var` sink at 472 -- and the taint
query runs for 23 seconds. So the gap is the middle: the flow crosses
`new MemberOrder( $code )` into a constructor and then
`$this->getMemberOrderByCode( $code )`, both dynamic in PHP. Whether
php2cpg resolves either into a callee edge is UNVERIFIED; two attempts to
query the call graph failed on script errors and were abandoned rather than
guessed at. Recorded as 5.7, with the answer required before anything is
concluded about the fact tables.
Three engine defects had to be fixed before the scan could produce even
this result, and each had previously reported the plugin clean for a
different reason:
1577 regions, 0 scanned joern-parse failed where php2cpg succeeded
500 scanned, taint 0.05s a 1.49MB batch over Linux's 128KB argv cap
500 scanned, taint 21.7s the entry point was not recognised as one
The middle one is the one to remember. Every honesty mechanism in this
codebase labels a verdict -- suspicion, regions_unjudged, regions_unasked,
stated family limits -- and there no verdict was produced to label, so a
vulnerable plugin was reported clean with every counter agreeing.
What is established: the WordPress engine path works end to end. What is
not: detection on a real plugin. One checkout that does not find its CVE is
not yet evidence either way about the facts, and 5.7 has to answer whether
the call graph can carry the flow at all.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG