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).
Allow only http/https schemes and strip embedded credentials on outbound URLs
Reject any outbound URL whose protocol is not http/https, and refuse URLs carrying userinfo credentials before making the request.
Bad example
| 1 | // Only checks the host, ignores the scheme and userinfo. |
| 2 | function validate(rawUrl: string) { |
| 3 | const url = new URL(rawUrl); |
| 4 | if (!ALLOWED_HOSTS.has(url.hostname)) throw new Error('Host not allowed'); |
| 5 | return url; |
| 6 | } |
| 7 |
|
| 8 | // Passes: file:///etc/passwd, gopher://allowed-host:6379/_SET..., |
| 9 | // http://allowed-host@169.254.169.254/ (host parses as allowed, connects elsewhere) |
| 10 | await fetch(validate(userUrl)); |
Explanation (EN)
Without a scheme check, dangerous protocols (file:, gopher:, ftp:, data:) reach the client and can read local files or speak to internal TCP services. Embedded userinfo both leaks secrets in logs and can confuse host parsing/comparison, helping bypass the host check.
Objašnjenje (HR)
Bez provjere sheme, opasni protokoli (file:, gopher:, ftp:, data:) stižu do klijenta i mogu čitati lokalne datoteke ili komunicirati s internim TCP servisima. Ugrađeni userinfo i otkriva tajne u logovima i može zbuniti parsiranje/usporedbu hosta, pomažući zaobilaženje provjere hosta.
Good example
| 1 | function validateOutboundUrl(rawUrl: string): URL { |
| 2 | const url = new URL(rawUrl); |
| 3 | if (url.protocol !== 'http:' && url.protocol !== 'https:') { |
| 4 | throw new Error(`Disallowed scheme: ${url.protocol}`); |
| 5 | } |
| 6 | if (url.username || url.password) { |
| 7 | throw new Error('Credentials in URL are not allowed'); |
| 8 | } |
| 9 | if (!ALLOWED_HOSTS.has(url.hostname)) { |
| 10 | throw new Error('Host not allowed'); |
| 11 | } |
| 12 | return url; |
| 13 | } |
| 14 |
|
| 15 | await fetch(validateOutboundUrl(userUrl), { redirect: 'manual' }); |
Explanation (EN)
Pinning the protocol to http/https eliminates file/gopher/ftp/data exploitation paths, and rejecting userinfo removes both a credential-leak vector and a host-spoofing trick. Combined with the host allowlist, the request surface is tightly constrained.
Objašnjenje (HR)
Vezivanje protokola na http/https uklanja file/gopher/ftp/data eksploatacijske putove, a odbijanje userinfa uklanja i vektor curenja vjerodajnica i trik spoofanja hosta. Uz allowlist hostova, površina zahtjeva je čvrsto ograničena.
Notes (EN)
OWASP SSRF Cheat Sheet lists scheme restriction and credential stripping as baseline input validation for any URL that becomes a request.
Bilješke (HR)
OWASP SSRF Cheat Sheet navodi ograničenje sheme i uklanjanje vjerodajnica kao osnovnu validaciju ulaza za svaki URL koji postaje zahtjev.
Exceptions / Tradeoffs (EN)
If a feature must support an additional scheme (e.g. data: URIs for inline images decoded in-process, never network-fetched), handle it on a separate, explicitly-reviewed path rather than widening the network fetch allowlist.
Iznimke / Tradeoffi (HR)
Ako značajka mora podržavati dodatnu shemu (npr. data: URI-je za inline slike dekodirane u procesu, nikad mrežno dohvaćene), obradite to na zasebnom, eksplicitno pregledanom putu umjesto širenja allowlista za mrežni fetch.