Fix server fetches a URL the caller controls in Express
An outbound HTTP request is made to a URL that came from the caller. The server can reach hosts the caller cannot - cloud metadata endpoints, internal admin services, databases bound to localhost - so this turns the server into a proxy into its own network. Validate the destination against an allowlist before fetching it.
high likely Express CWE-918 / OWASP A10:2021
The vulnerable pattern in Express
This finding comes from the Express fixture in the owlwarden test suite. The destination of this request comes from the caller, so they choose which host the server connects to. That includes hosts they cannot reach themselves: the cloud metadata endpoint that hands out IAM credentials, internal services that skip authentication because they are 'not exposed', and anything bound to localhost.
The corrected handler
Validate before the request and refuse redirects.
const target = assertAllowedUrl(req.body.url)
const upstream = await fetch(target, { redirect: 'error' })
If you are not using Express
Check the destination against an allowlist of hosts before fetching it. Blocklists do not work here: DNS rebinding, redirects, and IPv6-mapped addresses all defeat them.
Check your own repository
npx owlwarden scan
npx owlwarden explain ssrf
Runs on your machine. No account, no telemetry, no network unless you ask. In CI, SARIF uploads to code scanning and the exit code is the gate.
Other Express checks
Rules with a tested Express example.
- cors-permissive medium Cross-origin policy accepts any origin
- hardcoded-secret high Credential hardcoded in source
- insecure-cookie medium Cookie set without its protective attributes
- install-lifecycle-script medium Package declares an install-time script
- open-redirect medium Redirect target comes from the caller
- security-headers-missing medium Security headers are not configured
- sensitive-data-logged medium Sensitive data written to a log
- sql-injection high SQL query built by string interpolation
- stack-trace-leak high Stack trace leaked in error response
- weak-crypto high Broken cryptographic primitive protecting a secret