Attachment downloads should check the record they belong to
Your GET /tickets/:id handler checks that the caller can see the ticket. The files attached to that ticket come from GET /files/:fileId, and that route only checks that someone is logged in. So anyone holding a file ID
Your GET /tickets/:id handler checks that the caller can see the ticket. The files attached to that ticket come from GET /files/:fileId, and that route only checks that someone is logged in.
So anyone holding a file ID can download a screenshot from another customer's support ticket. File IDs end up in notification emails and server logs, and they keep working after a user loses access to the ticket.
What I'd do:
- Store the parent on the file row (
parent_type,parent_id). The download route loads the parent and runs the same check the parent's own endpoint runs. - If you hand out signed storage URLs, sign them only after that check passes and keep the expiry short, a few minutes is plenty.
- Thumbnails, previews and "download all as zip" usually have their own routes. Give them the same check, they are the ones that get missed.
- Add a test where user A uploads to a ticket and user B from another tenant requests the file ID directly. B should get a 404.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.