Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Enforce object-level authorization on every record access (BOLA)
Any endpoint that uses a client-supplied object ID must verify the user is allowed to access that specific object.
Bad example
| 1 | app.get('/documents/:id', async (req, res) => { |
| 2 | const doc = await db.document.findUnique({ where: { id: req.params.id } }); |
| 3 | if (!doc) return res.status(404).json({ message: 'Not found' }); |
| 4 | return res.json(doc); |
| 5 | }); |
Explanation (EN)
The handler fetches a record by a user-controlled ID without verifying ownership or policy access. Attackers can enumerate or guess IDs and access other users' data.
Objašnjenje (HR)
Handler dohvaća zapis prema ID-u koji dolazi od klijenta bez provjere vlasništva/politike pristupa. Napadač može pogađati/enumerirati ID-eve i pristupiti tuđim podacima.
Good example
| 1 | app.get('/documents/:id', async (req, res) => { |
| 2 | const userId = req.auth.userId; |
| 3 |
|
| 4 | const doc = await db.document.findFirst({ |
| 5 | where: { id: req.params.id, ownerId: userId } |
| 6 | }); |
| 7 |
|
| 8 | if (!doc) return res.status(404).json({ message: 'Not found' }); |
| 9 | return res.json(doc); |
| 10 | }); |
Explanation (EN)
The query enforces authorization at the data layer by scoping the object lookup to the authenticated user (or policy). If the record isn't accessible, it behaves like not found.
Objašnjenje (HR)
Upit provodi autorizaciju na data layeru tako da lookup ograniči na autentificiranog korisnika (ili politiku). Ako zapis nije dostupan, ponaša se kao da ne postoji.
Notes (EN)
Do not rely on comparing the session userId to an ID parameter as a universal fix. Enforce per-object access checks (ownership, org membership, ACLs, roles) for every action (read/update/delete). Prefer unpredictable IDs (UUID/GUID), but never treat them as authorization.
Bilješke (HR)
Nemoj se osloniti na usporedbu session userId s ID parametrom kao univerzalno rješenje. Provodi per-object provjere (vlasništvo, org članstvo, ACL, uloge) za svaku akciju (read/update/delete). Preferiraj nepredvidive ID-eve (UUID/GUID), ali nikad ih ne tretiraj kao autorizaciju.