Quick answer: CORS, CSRF, and CSP are not three names for the same problem. CORS is a browser mechanism, based on HTTP headers, that determines when code from one origin may read a response from another origin. CSRF is an attack in which a victim's browser is induced to send an authenticated request the user did not intend to make. CSP is a policy sent by a site to the browser to limit which resources and code a page may load or execute. In practice: trouble reading an API from another origin points to CORS; an unwanted action performed with the user's session points to CSRF; unauthorized script, frame, or resource execution or loading points to CSP.
Why CORS, CSRF, and CSP get mixed together
All three appear in web security, involve browser decisions, and often surface during front-end debugging. They also refer to concepts such as origins, HTTP headers, and external resources. The similarity ends there. Each one answers a different question and acts in a different direction of the flow.
For CORS, the question is whether the browser may expose to JavaScript from one origin a response received from another. For CSRF, the question is whether an attacker-controlled site can trigger an action on the target server using credentials the browser sends automatically, such as session cookies. For CSP, the question is what the already loaded document is allowed to execute, fetch, or embed.
Matrix: CORS vs. CSRF vs. CSP
| Aspect | CORS | CSRF | CSP |
|---|---|---|---|
| What it is | HTTP-header mechanism for cross-origin sharing | Request-forgery attack in an authenticated context | Browser-enforced content security policy |
| Core question | May this JavaScript read the response from that other origin? | Can another site make the user's browser perform an authenticated action? | Which resources and execution modes may this page use? |
| Main layer | Browser plus the response from the server providing the resource | Application and server receiving authenticated actions | Browser following the policy declared by the site |
| Typical problem | Fetch or XMLHttpRequest blocked by origin policy | Unwanted POST, PUT, PATCH, or DELETE using the victim's session | Injected script execution, unauthorized resource loading, or unwanted embedding |
| Common controls | Access-Control-Allow-Origin, preflight, allowed methods and headers, credentials | Anti-CSRF token, SameSite, Origin or Referer validation, Fetch Metadata, custom headers | Content-Security-Policy with directives such as script-src, default-src, connect-src, and frame-ancestors |
| What it does not replace | Authentication, authorization, and CSRF protection | Authorization checks, XSS remediation, and resource-loading policy | Input sanitization, authorization, CORS, or CSRF protection |
| Debugging signal | CORS error in the console, OPTIONS preflight, or response not exposed to script | An action occurs without the user's intent while the user is already authenticated | The console reports a Content Security Policy violation or a resource is blocked by a directive |
CORS: permission to read across origins
The same-origin policy restricts how a document or script from one origin interacts with resources from another. An origin is defined by the combination of scheme, host, and port. CORS, or Cross-Origin Resource Sharing, allows the server to tell the browser which other origins may access a response in a cross-origin context.
The best-known header is Access-Control-Allow-Origin. Depending on the request, the browser may first send an OPTIONS preflight to ask which methods and headers are permitted. If the response does not satisfy the policy, JavaScript does not receive normal access to the response content.
The key distinction is that CORS is primarily a rule about the browser sharing a response with calling code. It is not a server firewall and it does not replace authentication or authorization. Non-browser clients, such as backend services and HTTP tools, do not depend on browser CORS enforcement to decide whether they can make a request.
Why a CORS error does not mean the request never reached the server
Some so-called simple requests may be sent without a preflight, including certain GET, HEAD, and POST requests with limited headers and content types. The server still has to process them safely. If the origin is not allowed by CORS, the browser may hide the response from attacker-controlled JavaScript, but that does not undo a side effect the server has already performed. This is one reason CORS must not be treated as a CSRF defense.
Credentials add another common source of confusion. When a CORS response is shared for a request that includes credentials, the configuration must be more restrictive. A wildcard in Access-Control-Allow-Origin is not a generic permission for credentialed responses, and third-party cookie policies still apply.
CSRF: the problem is the forged action, not reading the response
Cross-Site Request Forgery exploits the fact that browsers may automatically attach credentials to a request, especially session cookies. An attacker prepares a page or flow that causes the victim's browser to send a request to an application where the victim is already authenticated. If the server accepts the request merely because the session cookie is present, an action may occur without the user's intent.
The attacker does not necessarily need to read the response for the attack to succeed. If an operation such as changing an email address, adding a key, changing a setting, or starting a transaction is completed on the server, blocking response reading through CORS does not fix the weakness.
Defenses that actually belong to the CSRF problem
- Anti-CSRF token: stateful applications can use the synchronizer token pattern, where the server issues a secret, unpredictable value and validates it on state-changing requests.
- SameSite cookies: reduce cookie sending in many cross-site contexts. OWASP treats SameSite as an important layer, but not as a universal replacement for anti-CSRF controls.
- Origin verification: the server can validate Origin and, in fallback scenarios, Referer, comparing the request source with the expected target origin.
- Fetch Metadata: headers such as Sec-Fetch-Site provide extra context that can help reject suspicious cross-site requests.
- Custom request header for APIs: in AJAX or API architectures, requiring a header that an external site cannot add as a simple request can be part of the defense, provided the CORS policy is restrictive and the API does not also accept unsafe simple content types as an alternative.
The right defenses depend on the architecture. A traditional form, an SPA using cookies, and an API using explicit bearer tokens have different attack surfaces. It is also important to avoid state changes through GET requests, because methods considered safe receive special treatment in browsers and cookie policies.
CSP: restrict what the page may load and execute
Content Security Policy is delivered mainly through the Content-Security-Policy response header. The policy contains directives that tell the browser which sources and behaviors are allowed. script-src controls permitted JavaScript sources and execution modes; style-src does the same for styles; img-src controls images; connect-src restricts destinations for script-initiated connections; frame-ancestors controls who may embed the page.
One of CSP's primary uses is to reduce the risk and impact of XSS. A strict policy can block unauthorized inline scripts, inline event handlers, URLs using the JavaScript scheme, and external sources that are not allowed. Nonces or hashes can authorize specific scripts without broadly enabling inline execution.
CSP is defense in depth. It does not make it safe to insert unsanitized input into HTML and does not replace encoding and sanitization. It also does not decide whether a remote server should share its response with another origin, which is CORS, nor does it verify that an authenticated action was truly requested by the user, which is the CSRF problem.
Why connect-src still does not turn CSP into CORS
connect-src can stop the current page from using fetch, XMLHttpRequest, WebSocket, and related connections to unauthorized destinations. That can look like CORS at first glance, but the direction is different. CSP is a rule declared by the page's own site to restrict that page's behavior. CORS is the target server's response telling the browser whether a cross-origin response may be exposed to calling code. Both controls can apply to the same request.
Three mini scenarios to identify the right concept
Scenario 1: the SPA calls the API and the console shows an origin block
The front end at https://app.example calls https://api.example. The API works when tested with an HTTP tool, but the browser does not expose the response to JavaScript. The first concept to investigate is CORS: Access-Control-Allow-Origin, preflight, methods, headers, and credentials. API authentication remains a separate concern.
Scenario 2: an external site triggers an email change for a signed-in user
The application uses a session cookie. The user visits a malicious site that can send a form-compatible request to the email-change endpoint. The response does not need to be readable. If the server performs the change simply because it received the cookie, the issue is CSRF. The defense must validate intent, for example with a token, appropriate SameSite settings, origin verification, or equivalent controls for the architecture.
Scenario 3: a comment field allows injected JavaScript to execute
The primary vulnerability is XSS, and CSP can reduce the payload's ability to execute or load unauthorized code. The root fix is still to handle input and output safely. A strict policy acts as defense in depth. CORS configuration does not repair the injection, and an anti-CSRF token does not stop JavaScript that is already executing inside the trusted origin.
How to quickly choose which defense to investigate
- If the failure is reading a cross-origin response in the browser, investigate CORS and the same-origin policy.
- If the failure is an authenticated action occurring without the user's intent, investigate CSRF and how the server validates state-changing requests.
- If the failure is unauthorized code or a resource executing, loading, or being embedded, investigate CSP and, when injection exists, the underlying XSS cause.
- If more than one issue appears in the same flow, handle each layer separately. It is common for an SPA to need correct CORS, CSRF protection because it uses cookies, and a strict CSP at the same time.
Configuration mistakes that keep the concepts confused
- Opening Access-Control-Allow-Origin broadly to fix any error: this may resolve an integration symptom, but it can expose responses to unnecessary origins and does not create application authorization.
- Treating preflight as an anti-CSRF barrier: simple requests exist partly for compatibility with historical cross-site submission patterns. The endpoint needs its own controls.
- Using CSP as a substitute for sanitization: CSP reduces execution vectors, but MDN recommends treating it as one part of a broader XSS defense strategy.
- Treating Origin as the user's identity: origin helps with browser policies and CSRF checks, but authentication and authorization still require their own server-side controls.
- Forgetting that XSS can weaken CSRF defenses: malicious code running inside the application's origin can, in many scenarios, read tokens available to JavaScript and send requests as the application itself.
A compact way to remember the difference
CORS is about sharing responses across origins. CSRF is about forging authenticated actions. CSP is about limiting page behavior and resource loading. The right defense follows from the right question: who is trying to read, who is trying to act, and what is the page allowed to execute or load?





