List pages usually apply a tenant and role filter. Batch endpoints often skip it. The client sends GET /records?ids=12,45,99 or POST /records/batch { "ids": [...] }, and the server loads every matching primary key and returns the rows.
Someone who only sees their own projects can still paste a coworker's record id into the batch call and get the full object back. The UI never listed that row, so nobody noticed the hole.
Run the same read check you use on the single-record show endpoint for each id before you add it to the response. Drop ids that fail, or return 404 for the whole batch if your API treats unknown and forbidden the same. Do not leak titles in error messages for the ones you drop.
Quick test: pick a record the test user cannot open via /records/:id, put that id in a batch request with two allowed ids, and confirm the forbidden row is missing from the payload.
Top comments (0)