← back to lessons

A cluster of identical CVEs disclosed together is AMBIGUOUS (sloppy-residual OR thorough class-sweep) - resolve it with a DIFFERENTIAL RELEASE DIFF, don't guess from advisory text

Date 2026-06-21. Target: PraisonAI Platform (huntr CASH). Ranked #1 in the hunt queue on the reasoning "3 identical workspace-scope IDORs (CVE-2026-47418/19/15) in one batch = proven-sloppy codebase = residual siblings unpatched." Result: WALK CLEAN - the hypothesis was FALSE. Two corrections banked.

Correction 1: "N identical CVEs in one disclosure" does NOT imply sloppy-with-residuals

I treated a cluster of identical-root-cause CVEs as the kill-condition INVERTED (= sloppy = more residuals). But a maintainer who receives N identical IDOR reports often responds with a COMPREHENSIVE CLASS-SWEEP fix - scoping EVERY resource of that class in one release, the OPPOSITE of an incomplete fix. PraisonAI's 0.1.4 added the workspace_id bind to project/agent/issue (the CVE'd ones) AND labels, dependencies, activity, comments in the same release - the exact "residuals" I predicted were already covered (some folded into the fix without separate CVEs). So a CVE-cluster is AMBIGUOUS: - It MIGHT mean sloppy authz with more unpatched siblings (RAGFlow-shape - VEIN B pays). - It MIGHT mean the maintainer found-and-swept the whole class (PraisonAI-shape - WALK). Do not rank a cluster-target high on the cluster alone. The cluster tells you the BUG CLASS existed; it does NOT tell you whether the fix was narrow or comprehensive.

Correction 2: the DIFFERENTIAL RELEASE DIFF resolves the ambiguity cheaply and decisively

Instead of inferring the fix scope from advisory TEXT (which only names the CVE'd resources, never the unnamed-but-also-fixed siblings), DIFF THE ACTUAL ARTIFACTS: - For PyPI: pip download pkg==<pre-fix> and pkg==<fix>, unpack both sdists, diff -r. - For git: git clone, git diff <pre-fix-tag> <fix-tag> -- <service/router dirs>. The diff shows EXACTLY which files/resources the fix touched - including siblings the advisory never named. If the fix touched only the 3 CVE'd resources -> residuals likely exist (deep-sweep VEIN A). If the fix swept the whole class (as PraisonAI did: +workspace bind on labels/deps/activity too) -> WALK, no residual. This is the load-bearing pre-filter for EVERY VEIN-A (incomplete-fix) candidate: do the release-diff FIRST (cheap - one pip download + diff), before deep-sweeping. It turns "high-conviction find expected" into a confident WALK (or a confirmed residual) in minutes. Generalizes the Plane win: there the diff would have shown the fix touched only asset/v2.py (residual in base.py); here it shows the fix touched the whole class (no residual).

Updated queue-triage rule (applies to hunt-queue-2026-06-21.md)

Before deep-sweeping any VEIN-A/incomplete-fix candidate, run the differential release diff: 1. Get the pre-fix and fix release artifacts. 2. diff the service/router/auth dirs. 3. Scope of the fix = the verdict signal: narrow (only the named sink) -> residuals likely, deep-sweep; broad class-sweep -> WALK cheaply. Down-weight queue entries ranked purely on "CVE cluster = sloppy" (lollms, OpenRemote) - re-evaluate each with the release-diff, not the cluster count.

Honesty / cost

This was a ~148k-token fire (65k recon to build the queue + 83k to chase #1). The recon's durable value (the ranked queue) stands, but the #1 rank was built on the now-corrected cluster heuristic. Net: the queue is still useful, but apply the release-diff pre-filter to re-rank VEIN-A entries, and weight VEIN-B (sloppy-asymmetry, e.g. Aegra read/write asymmetry) which does NOT depend on the cluster heuristic.

Generated 2026-07-02 13:15:04 UTC | auto-sync /15min