Comparison

corsproxy.dev vs cors.sh: a side-by-side comparison

Both managed CORS proxies, both running on Cloudflare's edge. Unlike our hosted service and most competitors on our wider comparison, cors.sh publishes its code, so this comparison cites their own spec rather than only their marketing page.

· ~5 min read · Updated Oct 13, 2026

Disclosure: corsproxy.dev is our product. cors.sh figures come from their pricing page, homepage, and their own public source repo (specifically SPEC.md, which they describe as "the source of truth for how the service behaves") as of the date above.

At a glance

  cors.sh corsproxy.dev
Free tier10,000 requests, 5 GB / month500 requests / day (about 15,000 / month), 250 MB / day
Paid planPro $4/month: 500,000 requests, 500 GB, no hourly capPro $5/month: 20,000 requests/day (~600k/month), 10 GB/day
Auth modelKey is public by design; the browser's Origin header is the real authenticator for live_ keysAPI key is the secret; optional per-key origin lock (a browser-side protection only)
Rate limitingDurable Object, but only on test_ keys (30/10s); live_ keys have no short-window cap, only the monthly quotaNo short-window cap on any key; a per-account daily quota, counted atomically in a Durable Object
Blocks private-network targets (SSRF)No: not in their documented request checks (origin, target allowlist, size, rate; no IP/network filtering listed)Yes, with limits: literal private addresses are refused, hostnames are checked by a separate DNS lookup before the fetch (fails open if the resolver errors), and redirects aren't followed
Response size cap enforcement6 MB, checked via Content-Length; their own spec flags the no-Content-Length case as an open gap ("mid-stream cutoff when length absent ⛳")10 MB; the response is buffered, so an oversized one fails with 502 RESPONSE_TOO_LARGE whether or not the upstream declares a length
Open source / self-hostYes, MIT: the full product monorepo (proxy worker, Next.js console, Stripe billing, Auth.js), built to run as their SaaS rather than as a drop-in self-hostThe hosted service isn't open source. We publish a separate, simpler open-source CORS relay (MIT, one Go file) you can self-host
Keep third-party API keys out of the browserNot offeredYes: managed upstream headers
Request URLproxy.cors.sh/<url> + x-cors-api-key headerapi.corsproxy.dev/proxy?url=URL&key=KEY

Where cors.sh is ahead

Where corsproxy.dev is ahead

SSRF filtering in the proxy itself

cors.sh's SPEC.md lists the request checks they run: origin pinning, per-key target allowlists, the 6 MB size cap, rate limiting. Private-network and internal-address filtering isn't on that list, so nothing in the proxy as documented stops a live_ key with no allowedTargets from being pointed at http://169.254.169.254/ or an internal hostname. The backstop for both services is the same: a Worker on Cloudflare's edge can't reach private networks.

corsproxy.dev adds a layer on top of that. Literal private, loopback, link-local and metadata addresses are refused with 403 BLOCKED_HOST, and hostnames are resolved through Cloudflare's security resolver first, so a name that points at a private address is refused too. That check has limits we'd rather state than hide: it's a separate lookup before the fetch, it fails open if the resolver errors, and because resolve-then-fetch isn't atomic, DNS rebinding could in principle race it. Upstream redirects aren't followed; a 3xx comes back to your code as is. See how a CORS proxy can be abused for the wider argument.

A small open-source relay you can run yourself

cors.sh's source being public is notable; most competitors on our wider list aren't open at all. But their repo is the whole product: a Next.js console, Stripe billing, Auth.js accounts, D1 and KV bindings, built to run their own SaaS. Our hosted service isn't open source. What we publish is a simpler open-source CORS relay: one Go file with no external service dependencies, run with go run main.go or a single Docker container. It has no accounts, keys, daily quotas or managed upstream headers, and it forwards request headers (including Cookie and Authorization) as is, so review its settings before exposing it publicly.

Managed upstream headers

If your frontend calls an API that needs a secret key, corsproxy.dev can attach it server-side per request so it never ships to the browser. cors.sh's model doesn't have an equivalent; see calling OpenAI, Notion, and Google Sheets without leaking your API key.

Rate limiting on both

Neither service puts a short-window brake on production keys. cors.sh's Durable Object limiter (30 requests per 10 seconds) applies only to test_ keys; live_ keys rely on the monthly quota. corsproxy.dev has no per-second limit on any key: every request counts against a per-account daily quota, enforced atomically in a Durable Object. The practical difference is the size of the bucket a misused key can drain before it stops.

Switching between them

const target = 'https://api.example.com/data';

// cors.sh
fetch('https://proxy.cors.sh/' + target, {
  headers: { 'x-cors-api-key': 'live_YOUR_CORS_SH_KEY' }
});

// corsproxy.dev
fetch(`https://api.corsproxy.dev/proxy?url=${encodeURIComponent(target)}&key=YOUR_CORSPROXY_DEV_KEY`);

Note the different auth shape: cors.sh sends the key as a header with the target unencoded in the path; corsproxy.dev takes the target as a URL-encoded query parameter with the key alongside it (or as an X-API-Key header for server-side callers). Not a drop-in swap either direction; budget a few minutes to update the call site, not just the base URL.

Which one to pick

Try it

Get a free API key — 500 requests/day, no credit card.