Chapter 2 · Practice 4 of 4
Protect the indirect paths: files, search, exports and nested objects
Why it matters
The main CRUD endpoints usually get checked. The leaks come from side doors:
- Files and object storage. OWASP's cheat sheet says static resources and cloud buckets need access control matched to the data's sensitivity. Serve private files through short-lived signed URLs generated after an authorization check, and keep buckets private.
- Search and autocomplete. A search index built from all tenants' data must filter by the caller's access, or the suggestions list becomes a data leak.
- Exports and reports. "Download all" often runs a separate query path written months later.
- Nested and related objects.
POST /projects/12/taskswithassigneeId: 77: is user 77 in project 12, and may the caller assign them? Is project 12 yours at all? - GraphQL. Each resolver needs its own check, because a query can reach an object through any relationship.
- Caches. A cached response keyed only by URL can serve one user's data to the next.
When you add a feature, list every way it can read or write data and confirm each one goes through the same scoped access layer.
Do
- Generate signed file URLs only after an authorization check, with short expiry
- Filter search results by the caller access before returning them
- Validate that referenced IDs in a request belong to the same scope