easterbrooka/mike: IDOR in tabular review document access closed

easterbrooka patched a CWE-639 authorization bypass in the tabular review routes, where four endpoints accepted caller-supplied document IDs without verifying the caller had read access to the underlying documents.

securitydiscovery

The vulnerability was concrete. A free-account attacker could create a review, supply foreign document UUIDs in the document list, and have the server fetch bytes from R2, run LLM extraction over them, and return verbatim text through the standard review GET - all without any access check on the supplied IDs. The affected endpoints were review creation, review patching, cell regeneration, and the full generation path.

The fix is a single access-filtering helper that checks the existing ownership conditions (owner-of-doc or project member) and is applied at each entry point before any S3 fetch or LLM call. Review creation and patching drop unauthorized IDs silently. Cell regeneration refuses to fetch when the caller lacks access to the underlying document. The generation path filters IDs before the LLM call as defense-in-depth for any legacy cells that may have been seeded before this fix.

The fail-closed behavior is intentional but quiet: unauthorized IDs are dropped rather than returned as 403s, so legacy clients passing stale IDs don't error out the entire review. For collaborators who aren't the document owner, patching keeps already-attached cells in place to avoid orphaning rows they can't directly access.

The PR merged in under a minute, characteristic of a security hotfix.

So what If your fork exposes tabular review routes and accepts document IDs from the caller, check whether your access layer verifies read permission on each supplied ID before fetching bytes. The filtering helper in this commit is a direct model for that check.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?