Date 2026-06-21. Target: Nextcloud server (master, 35.0.0-dev). first_patched-verifier on CVE-2026-45157 (share tokens read share-owner's temp upload files). Result: honest downgrade to WALK. The incomplete-fix gap is REAL in source but NOT exploitable. Banked because it sharpens the Floor's REACHABILITY gate (distinct from disclosure / by-design).
CVE-2026-45157 fix added: UploadHome::getChildren() throws MethodNotAllowed (blocks listing the owner's upload-session ROOT), ChunkingV2Plugin::beforeGet blocks content read via GET, RootCollection disableListing. Set-difference at HEAD found two genuine sibling gaps:
- apps/dav/lib/Upload/UploadFolder.php:57 getChildren() - UNGUARDED. UploadHome::getChild($uploadId) (not blocked) -> UploadFolder -> getChildren() lists a NAMED session's chunks via PROPFIND. The fix blocked the ROOT listing but not the per-session listing.
- ChunkingV2Plugin hooks GET/PUT/DELETE/MOVE/MKCOL but NOT COPY or PROPFIND - so a COPY content-read of an upload chunk bypasses the GET-only beforeGet guard.
Both confirmed in source, not disclosed, present at latest. It LOOKS like a cross-tenant incomplete-fix on a CASH target (Nextcloud HackerOne).
To exploit cross-tenant you must address a VICTIM's specific upload session, i.e. know its <uploadId>. But:
1. Enumeration is blocked - UploadHome::getChildren() throws (the fix), so you cannot LIST the victim's session ids.
2. The id is unguessable - the uploadId is a CLIENT-chosen folder name created via MKCOL, and Nextcloud's documented + web-UI convention is a RANDOM UUID (myapp-<uuid4>). No server-side predictable component.
So the only sessions you can address are ones whose UUID you ALREADY know - which are your OWN (you created them). Listing/reading your own in-flight chunks crosses no boundary. There is no path from "share-token holder" to "a victim's unguessable uploadId."
=> The source gap is a defense-in-depth incompleteness (the fix SHOULD also guard UploadFolder::getChildren + COPY for belt-and-suspenders), but it is NOT a practically exploitable cross-tenant vuln. Honest downgrade: low / informational. A HackerOne submission would be closed "requires knowledge of an unguessable upload token."
A source-confirmed incomplete-fix has THREE more gates to pass before it is a finding, and REACHABILITY is the one that kills "real-but-unreachable" gaps: - The unguarded sibling must operate on a resource the attacker can ADDRESS as a VICTIM's, not just their own. - If the resource is keyed by an UNGUESSABLE identifier (random UUID / crypto token / secret-derived path) AND there is no enumeration/leak primitive to obtain it, the cross-tenant path is closed - downgrade regardless of how real the missing guard is. - Specifically check: can the attacker ENUMERATE the id (a listing endpoint)? PREDICT it (sequential/timestamp/weak-random)? OBSERVE/LEAK it (logs, error messages, a shared channel, a co-tenant view)? If all three are no -> the gap is defense-in-depth, not exploitable. This is the inverse of the IDOR pattern: IDOR works because the id is guessable/enumerable; when the fix ALSO blocks enumeration and the id is a UUID, the residual sibling-gap is inert. Don't spend a live PoC on it (it would only prove you can read your OWN known-id session).
The Forgejo wrr5 win was reachable because the resource was the TOKEN OWNER'S OWN account (no victim-id needed - you authenticate AS the principal whose private data leaks). And the GitLab iterations IDOR was about ENUMERABLE group descendants. Reachability turns on: is the victim's resource addressable by the attacker? Own-account scope = always reachable; enumerable id = reachable; unguessable-unenumerable id = NOT reachable.