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).
Never log credentials, tokens, cookies, or whole request/error objects
Log only the specific scalar fields you need (status, route, request id). Never log auth headers, cookies, session tokens, passwords, or spread an entire request/user/error object into a log line.
Bad example
| 1 | // Express middleware |
| 2 | app.use((req, res, next) => { |
| 3 | logger.info({ req }, 'incoming request'); // dumps headers incl. Authorization + Cookie |
| 4 | next(); |
| 5 | }); |
| 6 |
|
| 7 | // Service catch block |
| 8 | try { |
| 9 | await zephr.getUserIdentity(sessionCookie); |
| 10 | } catch (err) { |
| 11 | // logs the failing fetch config, which carries the session cookie |
| 12 | logger.error({ err, sessionCookie }, 'profile fetch failed'); |
| 13 | } |
Explanation (EN)
Logging the whole `req` serializes the `Authorization` and `Cookie` headers; logging `err` from a fetch often includes the request config (headers, body) and logging `sessionCookie` directly hands an attacker a live session. Anyone with log access — or a log-shipping pipeline, or a leaked log file — now has credentials. This is OWASP A09 (Security Logging Failures) feeding A07 (Auth Failures).
Objašnjenje (HR)
Logiranje cijelog `req` objekta serijalizira `Authorization` i `Cookie` zaglavlja; logiranje `err` iz fetch poziva često uključuje konfiguraciju zahtjeva (zaglavlja, tijelo), a izravno logiranje `sessionCookie` napadaču predaje aktivnu sesiju. Svatko s pristupom logovima — ili log pipeline, ili procurena log datoteka — sada ima kredencijale. Ovo je OWASP A09 koji hrani A07.
Good example
| 1 | // Express middleware — log a deliberate, safe subset |
| 2 | app.use((req, res, next) => { |
| 3 | logger.info({ method: req.method, path: req.path, reqId: req.id }, 'incoming request'); |
| 4 | next(); |
| 5 | }); |
| 6 |
|
| 7 | // Service catch block — log message + status, not the carrier object |
| 8 | try { |
| 9 | await zephr.getUserIdentity(sessionCookie); |
| 10 | } catch (err) { |
| 11 | logger.error( |
| 12 | { err: err instanceof Error ? err.message : 'unknown', route: '/blaize/profile' }, |
| 13 | 'profile fetch failed', |
| 14 | ); |
| 15 | } |
Explanation (EN)
Each log line carries an explicit allow-list of non-sensitive fields. The error is reduced to its message (and optionally a stack via a configured serializer that strips request bodies), and the session cookie is never named in any log call. You keep the debuggability (route, status, message) without the credential blast radius.
Objašnjenje (HR)
Svaka log linija nosi eksplicitnu dozvoljenu listu neosjetljivih polja. Pogreška je svedena na svoju poruku (i opcionalno stack preko konfiguriranog serijalizatora koji uklanja tijela zahtjeva), a kolačić sesije nikada se ne spominje u nijednom log pozivu. Zadržavate mogućnost debugiranja (ruta, status, poruka) bez radijusa eksplozije kredencijala.
Notes (EN)
Backed by OWASP A09:2021 and the OWASP Logging Cheat Sheet 'Data to exclude' list (passwords, session IDs, tokens, auth headers, full bank/payment data).
Bilješke (HR)
Temeljeno na OWASP A09:2021 i OWASP Logging Cheat Sheet popisu 'Data to exclude' (lozinke, ID-ovi sesija, tokeni, auth zaglavlja, potpuni bankovni/platni podaci).
Exceptions / Tradeoffs (EN)
In local development you may temporarily log more verbosely, but gate it behind an env check (e.g. NODE_ENV !== 'production') so it can never ship. Even then, never log raw passwords or tokens.
Iznimke / Tradeoffi (HR)
U lokalnom razvoju možete privremeno logirati opširnije, ali to zaštitite provjerom okruženja (npr. NODE_ENV !== 'production') tako da nikada ne dospije u produkciju. Čak i tada, nikada ne logirajte sirove lozinke ili tokene.