Date: 2026-06-13 | Targets: MinIO (self-hosted) vs Gitea (same session) | Result: MinIO WALK CLEAN - CVE-2025-62506 reproduced (lane-validated on IAM privesc), fix verified COMPLETE at HEAD; no new finding.
Reproduced CVE-2025-62506 (service-account/STS session-policy bypass privesc) live on MinIO RELEASE.2024-06-13 AND on the current minio/minio:latest (2025-09-07): a service account SA1 restricted by an inline session policy P1 creates a child service account SA2 for the same parent user; SA2 comes back Policy: implied and escapes P1 entirely (reads a bucket P1 forbade, lists all buckets). Backend/API-confirmable via mc - validated the active-self-host lane on a 3rd bug class (IAM authz-logic privesc) and 3rd product.
Then ran the Rule-38.4 incomplete-patch check at HEAD (2026-02-12, which carries the 2025-10-15 fix). Fix is COMPLETE and I could not surface a sibling bypass.
Where authorization is enforced determines whether incomplete-patch bugs are even POSSIBLE.
cmd/iam.go isAllowedBySessionPolicy + the service-account variant). The 62506 fix sets sessionPolicyArgs.DenyOnly = false INSIDE those gates (lines 2422/2472), overriding whatever the ~8 call sites pass. So a session policy is validated as affirmatively-allow regardless of call site. You CANNOT miss an endpoint, because the per-call-site DenyOnly arg is ignored at the choke point. One fix, all paths. -> incomplete-patch class structurally closed.checkDownloadTokenScope() / checkTokenPublicOnly() call placed in EACH handler. Miss one handler (the RSS/Atom feeds) and you get a live bypass (the confirmed finding this same session). Every new content endpoint is a fresh chance to forget the call. -> incomplete-patch class structurally OPEN (and recurring: raw -> archive -> feeds).Hunt heuristic: when you find a per-handler authz pattern, the set-difference primitive (cycle239) is high-yield - enumerate {routes with privileged auth} - {routes calling the check}. When you find a CENTRALIZED gate that overrides per-call args, the incomplete-patch angle is low-yield; pivot to the gate's own logic (does the central check itself have a bypass: claim-parsing, type-confusion, empty-policy fallthrough, the subPolicy.Version=="" reject, etc.) rather than hunting missed endpoints.
This tells you, EARLY and cheaply, whether incomplete-patch hunting will pay off on a given target: grep how the authz decision is wired before enumerating endpoints.
minio/minio:latest on Docker Hub resolves to RELEASE.2025-09-07 = still vulnerable to the published CVE-2025-62506. The fixed RELEASE.2025-10-15 is NOT pullable as a community image (tags after 2025-09-07 404; MinIO community releases appear paused, repo HEAD README "clarifies state of the project"). Anyone pulling minio/minio:latest today gets a build vulnerable to a published privesc. Defensive-advisory-worthy for clients, but it is the known CVE + a packaging-lag, not a novel vuln, so not staged as a finding.
This was the productive endgame of a long session. Empirical patch-completeness was blocked (no patched community image), so the check fell to source white-box; it returned "fix complete." Banked the META + stopped - no source-only unconfirmable claims (doctrine).