How a CORS proxy works — and how it can be abused
CORS proxies are powerful, useful, and — by default — a nice gift to anyone trying to scan internal networks or exfiltrate credentials. Here's the honest threat model, and the specific things corsproxy.dev does so ours isn't one of those.
What a CORS proxy does, mechanically
A CORS proxy is a small HTTP server that does two things:
- Accepts a request from a browser at
/proxy?url=https://target.example/path. - Makes that request server-to-server, forwards the response back, and adds the
Access-Control-Allow-Originheader the browser was missing.
Because the browser sees the response coming from the proxy's origin (and the proxy says any origin is welcome), CORS no longer blocks the JS from reading it.
The threats inherent to running one
The reason "open" CORS proxies on the public internet keep getting taken down: any code that can hit them can use them. Concretely:
Server-Side Request Forgery (SSRF)
If the proxy will fetch any URL, attackers send ?url=http://169.254.169.254/latest/meta-data/ (AWS metadata), ?url=http://10.0.0.5:9200/_search (an internal Elasticsearch), or ?url=http://localhost:6379/ (a Redis with no auth). The proxy makes the request from its network, returns the response. That's how cloud breaches start.
Credential laundering
If the proxy forwards the Authorization header it received, an attacker can use the proxy to call paid APIs with someone else's bearer token. The target API logs the proxy's IP, not the attacker's.
Bandwidth abuse
Without rate limits, anybody who finds the proxy can pull terabytes through it. The bill lands on whoever's hosting it.
Reflected attacks
If responses are passed through untouched, an attacker can use the proxy to serve arbitrary content from a domain that the target trusts. Set-Cookie headers, redirect chains, and JavaScript can all be weaponised this way.
What corsproxy.dev does about each
Private-network targets are blocked
Before any upstream fetch, we resolve and reject:
- IPv4 private ranges — RFC 1918:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - Loopback:
127.0.0.0/8,::1,localhost - Link-local:
169.254.0.0/16(this is the AWS/GCP metadata block) - Non-HTTP(S) schemes: no
file://,gopher://,data://
The check happens on the resolved IP, not the hostname, so http://localtest.me tricks don't work either.
We strip incoming Authorization headers
The proxy never forwards Authorization or Cookie headers from the browser to the upstream. If you need to authenticate to the upstream, you do it explicitly via the request body or query string — never via header replay.
Every request is rate-limited per-key
The managed API requires an API key. Each key has a daily quota enforced atomically via a Cloudflare Durable Object (one counter per user, no eventually-consistent overage). Hit the cap, get 429. The free tier is 100/day; paid tiers are higher but still bounded.
Response headers are sanitised
We strip Set-Cookie, Transfer-Encoding, and Connection-class headers from the upstream response before returning to the browser. Body content is passed through as-is — it's the user's data to read.
Audit logs
Every proxy request is logged for 30 days: the user_id, key_id, upstream URL, status, response time, and client IP. The user can see their own logs in the dashboard; the operations team has them for incident response.
What we deliberately don't do
- We don't cache responses. Caching a proxy response could leak data between users with similar URLs.
- We don't run a generic open proxy. There is no anonymous use; every request maps to an account.
- We don't expose
OPTIONSbehaviour beyond what's needed for preflight. The proxy is not a reverse proxy or an API gateway — it's narrow on purpose.
The self-hosted angle
If your security posture doesn't allow sending requests through a third party — fair — the Go binary on GitHub is the same code that powers most of the open-source proxy core. You configure your own allowed origins, blocked hosts, and rate limits. The MIT licence lets you fork it.
Self-hosting moves the security responsibility to you. The mitigations above are not on by default in the OSS binary unless you configure them.
Reporting a security issue
Found something? Email contact@corsproxy.dev. We respond to security reports within 24 hours and credit reporters when fixes ship.