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).
Compare secrets in constant time
Use timing-safe comparison for secrets and tokens, not === / !==.
Bad example
| 1 | if (providedToken !== expectedToken) { |
| 2 | throw new UnauthorizedException(); |
| 3 | } |
Explanation (EN)
String inequality short-circuits on the first differing byte, so response timing reveals how many leading bytes matched, enabling byte-by-byte recovery.
Objašnjenje (HR)
Usporedba stringova kratko se spaja na prvom različitom bajtu, pa vrijeme odgovora otkriva koliko se vodećih bajtova podudara, što omogućuje rekonstrukciju bajt po bajt.
Good example
| 1 | import { timingSafeEqual } from 'node:crypto'; |
| 2 |
|
| 3 | const a = Buffer.from(providedToken); |
| 4 | const b = Buffer.from(expectedToken); |
| 5 | if (a.length !== b.length || !timingSafeEqual(a, b)) { |
| 6 | throw new UnauthorizedException(); |
| 7 | } |
Explanation (EN)
timingSafeEqual compares all bytes in constant time after an explicit length check, so timing no longer leaks how much of the secret matched.
Objašnjenje (HR)
timingSafeEqual uspoređuje sve bajtove u konstantnom vremenu nakon eksplicitne provjere duljine, pa vrijeme više ne otkriva koliko se tajne podudaralo.
Notes (EN)
Always length-check before timingSafeEqual since it throws on buffers of differing length.
Bilješke (HR)
Uvijek provjeri duljinu prije timingSafeEqual jer baca grešku za buffere različite duljine.
Exceptions / Tradeoffs (EN)
Non-secret value comparisons (regular business logic) do not need constant-time comparison.
Iznimke / Tradeoffi (HR)
Usporedbe vrijednosti koje nisu tajne (obična poslovna logika) ne trebaju usporedbu u konstantnom vremenu.