Safeguard
Security Guides•

Does CORS stop CSRF? A myth versus fact explainer

CORS decides which sites can read your responses, not which can send requests. Learn why a strict CORS policy does not stop cross-site request forgery.

Safeguard Security Team
3 min read

No. CORS controls whether a page on another origin can read your response. It does not stop the browser from sending the request, and simple requests reach your server without any preflight. CSRF defence has to be built on the server with tokens, header checks or SameSite cookies.

Myth: "We have no CORS headers, so other sites can't hit our API"

Fact: without CORS headers, a script on another origin cannot read the reply. But the request still goes out. MDN explains that HTML forms have always been able to send certain cross-origin requests, so "anyone writing a server must already be protecting against cross-site request forgery." Those requests are sent without a preflight.

A request counts as simple when it uses GET, HEAD or POST, only safelisted headers, and a content type of form encoded, multipart or plain text. A forged form post fits that description.

Myth: "CORS blocks the request before it reaches us"

Fact: for simple requests, the server receives and processes the request. The browser only withholds the response from script. The side effect, such as transferring money or changing an email, has already happened.

Preflighted requests behave differently. When a request uses a method like PUT or DELETE, or a custom header, or a JSON content type, the browser first asks permission with an OPTIONS request. If your server does not approve the origin, the real request is never sent. That is why a custom header requirement works as a CSRF control for APIs, as the OWASP cheat sheet describes.

Myth: "Allowing credentials with a wildcard is fine"

Fact: browsers refuse that combination. MDN states that for credentialed requests the server must not use * for allowed origin, headers, methods or exposed headers. The real danger is the workaround. Some servers echo back whatever Origin header they receive and also allow credentials. That lets any site read authenticated responses. Compare the origin against an explicit allowlist instead, and send Vary: Origin when the value changes per request.

How CORS and CSRF defence fit together

  • Use CORS to decide which origins may read responses and call preflighted endpoints.
  • Use CSRF tokens or a required custom header to decide whether a state changing request is genuine.
  • Use SameSite cookies as an added layer so the browser withholds the session cookie on cross-site requests.
  • Keep the allowed origin list tight. The OWASP cheat sheet warns that a permissive policy, for example allowing all subdomains, weakens the custom header defence if one subdomain is taken over.

Quick check

If I set Access-Control-Allow-Origin to a single trusted site, am I protected from CSRF?

Not by that header alone. It limits who can read responses. Forged simple requests can still be sent, so keep tokens or a custom header requirement.

Why do browsers send an OPTIONS request first?

It is the preflight. The browser asks the server whether the real request is allowed when the method, headers or content type go beyond a simple request.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.