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).
Send a long-lived Strict-Transport-Security header on HTTPS responses
Set HSTS (Strict-Transport-Security) with max-age >= 1 year and includeSubDomains on all HTTPS responses, and redirect HTTP to HTTPS, to prevent protocol-downgrade and cookie-leak attacks.
Bad example
| 1 | // Serving over HTTPS but no HSTS, and HTTP is left reachable. |
| 2 | app.get('/', (req, res) => { |
| 3 | res.send('ok'); |
| 4 | }); |
| 5 |
|
| 6 | // or a too-short, subdomain-blind header copied from a blog |
| 7 | res.setHeader('Strict-Transport-Security', 'max-age=300'); |
Explanation (EN)
With no HSTS, a network attacker can sslstrip the connection: the victim's first request over http:// is intercepted and never upgraded, leaking cookies and credentials. A max-age of 300s effectively disables the protection between visits, and omitting includeSubDomains leaves auth/api subdomains exploitable.
Objašnjenje (HR)
Bez HSTS-a mrezni napadac moze izvesti sslstrip: zrtvin prvi zahtjev preko http:// se presretne i nikad ne nadogradi, otkrivajuci kolacice i vjerodajnice. max-age od 300s prakticki gasi zastitu izmedu posjeta, a izostavljanje includeSubDomains ostavlja auth/api poddomene iskoristivima.
Good example
| 1 | import helmet from 'helmet'; |
| 2 |
|
| 3 | app.use( |
| 4 | helmet.hsts({ |
| 5 | maxAge: 31_536_000, // 1 year |
| 6 | includeSubDomains: true, |
| 7 | preload: true, // only if you submit to the HSTS preload list |
| 8 | }), |
| 9 | ); |
| 10 |
|
| 11 | // Redirect any http request to https before HSTS can apply |
| 12 | app.use((req, res, next) => { |
| 13 | if (req.secure || req.headers['x-forwarded-proto'] === 'https') return next(); |
| 14 | return res.redirect(301, `https://${req.headers.host}${req.url}`); |
| 15 | }); |
Explanation (EN)
A one-year max-age with includeSubDomains tells browsers to refuse plain HTTP to the domain and all subdomains for a long window, killing downgrade attacks after the first secure visit. The redirect ensures the very first hop is upgraded. Behind a proxy/CDN, trust the proxy and check x-forwarded-proto.
Objašnjenje (HR)
Jednogodisnji max-age uz includeSubDomains govori preglednicima da dugo razdoblje odbijaju obicni HTTP prema domeni i svim poddomenama, cime se ubijaju downgrade napadi nakon prvog sigurnog posjeta. Redirect osigurava da je prvi skok nadograden. Iza proxyja/CDN-a vjeruj proxyju i provjeri x-forwarded-proto.
Notes (EN)
OWASP HTTP Strict Transport Security Cheat Sheet. preload also requires no exclusions and a valid cert across all subdomains.
Bilješke (HR)
OWASP HTTP Strict Transport Security Cheat Sheet. preload takoder zahtijeva nijednu iznimku i valjan certifikat na svim poddomenama.
Exceptions / Tradeoffs (EN)
Don't send HSTS over plain HTTP (it's ignored and signals confusion) or on localhost dev. Only add preload after you've committed to HTTPS-everywhere and submitted the domain — preload is hard to undo. If the proxy/CDN already injects HSTS, set it in one place, not both.
Iznimke / Tradeoffi (HR)
Ne salji HSTS preko obicnog HTTP-a (ignorira se i signalizira zabunu) ni na localhost dev-u. Dodaj preload tek nakon sto si se obvezao na HTTPS-svugdje i prijavio domenu — preload je tesko ponistiti. Ako proxy/CDN vec ubacuje HSTS, postavi ga na jednom mjestu, ne na oba.