Site AI Auditde la Internet Solutions

CORS Explained: The Misconfigurations That Expose Your Data

1 octombrie 20268 min de cititSecuritate și SSL
CORS Explained: The Misconfigurations That Expose Your Data

Short answer: CORS (Cross-Origin Resource Sharing) is a set of HTTP headers that tells browsers which other websites may read responses from your site. It is safe when you allow only a fixed list of trusted origins. It becomes dangerous when the server reflects any Origin header back, trusts the “null” origin, or matches domains loosely while also allowing credentials, because then any website a logged-in user visits can read that user’s private data from your site.

What CORS is and why browsers need it

Browsers follow the same-origin policy: a script loaded by one origin (a combination of scheme, host and port, such as https://shop.example) cannot read responses from another origin. Without this rule, any website you visited could quietly read your webmail, your bank balance or your customer account on another site, because the browser would attach your cookies to those requests.

Modern websites often need controlled exceptions. A front end on www.example.com may call an API on api.example.com, or a partner widget may need to fetch public data. CORS is the mechanism for those exceptions. The server answers with headers such as:

An important point that is often misunderstood: CORS relaxes security. It does not add protection to your server. Without any CORS headers, browsers already block other sites from reading your responses. Every CORS header you add opens a door, so each one needs a reason.

How a CORS request works

When a script on another origin makes a request, the browser adds an Origin header naming that site. For simple requests, it sends the request and then checks the response headers before letting the script see the result. For requests with other methods such as PUT or DELETE, or with custom headers or a JSON content type, the browser first sends a preflight OPTIONS request asking whether the real request is allowed.

Two consequences matter for security:

  1. The server decides, the browser enforces. If your server says “yes” to an origin, the browser trusts that answer completely.
  2. CORS only affects browsers. Tools like curl or server-side scripts ignore it. CORS is not an access control for your API; authentication and authorisation still have to be enforced on the server.

The MDN guide to CORS describes the full request flow if you need the details.

The five misconfigurations that expose data

Most real CORS vulnerabilities come from a handful of patterns. They are only serious when the response contains private data and credentials are allowed, but that combination is common on customer accounts, admin panels and APIs.

1. Reflecting any origin

The server copies whatever arrives in the Origin header into Access-Control-Allow-Origin and also sends Access-Control-Allow-Credentials: true. This is usually done to “make CORS errors go away” during development. The effect is that every website on the internet is trusted, and a malicious page can read the logged-in user’s data.

2. Trying to combine a wildcard with credentials

Browsers refuse Access-Control-Allow-Origin: * together with credentials. Developers who hit this error often switch to reflecting the origin instead, which creates problem number 1. A wildcard is fine only for truly public, non-personal data with no credentials.

3. Trusting the “null” origin

Some servers allow Origin: null because local files or redirects send it during testing. Attackers can produce a null origin from a sandboxed iframe, so allowing it is almost the same as allowing everyone.

4. Loose origin matching

Checks such as “origin ends with example.com” or “origin contains example.com” can be bypassed with domains like attacker-example.com or example.com.attacker.net. Regular expressions with an unescaped dot have the same weakness.

5. Allowing HTTP or forgotten subdomains

Trusting http:// origins lets anyone who can tamper with unencrypted traffic inject a script from that origin. Trusting every subdomain means a single vulnerable or taken-over subdomain can read your API. Our guide to subdomain takeover prevention explains how forgotten DNS records turn into that kind of foothold.

What an attack looks like in practice

It helps to see why a single header line matters. Imagine an online shop whose account API at /api/account returns the customer’s name, e-mail address, delivery address and recent orders. The developer configured the API to reflect any origin with credentials allowed.

  1. An attacker publishes a page on a domain they control, perhaps disguised as a discount voucher or a quiz.
  2. A customer who is logged in to the shop opens that page in the same browser.
  3. A script on the attacker’s page calls the shop’s account API with credentials included. The browser attaches the customer’s session cookie, as it normally would.
  4. The shop’s server sees a valid session and returns the customer’s data, together with a header saying the attacker’s origin may read it.
  5. The script reads the response and sends the data to the attacker’s server.

The customer sees nothing unusual, and the shop’s logs show an ordinary, authenticated request. The same pattern can expose API keys shown in a dashboard, anti-forgery tokens, or data in an admin panel if an administrator visits the wrong page. That is why CORS problems on logged-in areas deserve the same attention as other data leaks.

How to check your own CORS configuration

You can test the basic behaviour with a single command. Send a request with a made-up origin and look at the response headers:

curl -s -I -H "Origin: https://evil.example" https://api.yoursite.com/account

Then read the result:

Also look at the browser’s developer tools on your own site. CORS errors in the console tell you which cross-origin requests your front end really makes, which is the list you actually need to allow.

How to configure CORS safely

  1. Start from nothing. Do not add CORS headers unless a specific cross-origin use needs them.
  2. Use an explicit allowlist. Compare the incoming origin with a fixed list of full origins, exact string match, including scheme and port. Return that single origin when it matches; return no CORS header otherwise.
  3. Allow credentials only when necessary. Public data does not need cookies. If credentials are required, the allowlist must be strict.
  4. Send Vary: Origin. When the response depends on the origin, caches and CDNs must not serve one origin’s headers to another.
  5. Limit methods and headers. Allow only the methods and request headers the front end uses.
  6. Keep CORS separate from authorisation. Every request must still be checked on the server: is this user allowed to see this data?
  7. Review after changes. New subdomains, apps and partners tend to be added to the allowlist and never removed.

Frameworks and web servers usually provide a CORS module or middleware. Use it with an explicit list rather than writing header logic by hand, and avoid options that allow all origins in production.

CORS compared with other browser security headers

CORS is often confused with other headers because they all mention origins. They do different jobs:

MechanismWhat it controlsWho sets it
CORSWhich other origins may read your responsesThe server being called
Content-Security-PolicyWhich sources your own page may load and runThe page itself
X-Frame-Options / frame-ancestorsWho may embed your page in a frameThe page itself
SameSite cookiesWhen cookies are sent with cross-site requestsThe server setting the cookie

They complement each other. SameSite cookie attributes, for example, reduce what a cross-site request can do even when CORS is misconfigured. See secure cookie flags and the overview of HTTP security headers for how the pieces fit together.

Where Site AI Audit fits

Site AI Audit checks the security basics that every public website should have: the SSL certificate and its expiry, the HTTP to HTTPS redirect, security headers and exposed software versions. It looks at your site from the outside, the way visitors see it, and explains each finding in plain words with a suggested fix. CORS rules on private APIs and logged-in endpoints need the manual tests described above, or a deeper security review, because they depend on how your application handles each request. For the public-facing basics, you can start with a free check.

Related reading

The bottom line

CORS opens controlled holes in the browser’s same-origin policy. Keep those holes small: no CORS headers unless needed, an exact allowlist of full origins, credentials only when required, Vary: Origin, and real authorisation on the server. Never reflect arbitrary origins or trust “null”.

FAQ

Is Access-Control-Allow-Origin: * dangerous?

Not by itself. Browsers do not allow the wildcard together with credentials, so it only exposes data that anyone could fetch anyway. It becomes a problem when the endpoint returns private data based on something other than cookies, such as network location.

Does CORS protect my API from attackers?

No. CORS is enforced by browsers only, and tools like curl ignore it. Your API still needs authentication and authorisation checks on the server for every request.

Why do I get CORS errors on my own website?

Your page is calling a different origin, such as another subdomain, port or scheme, and that server does not allow your origin. Add your exact origin to its allowlist instead of allowing all origins.

What is a CORS preflight request?

It is an OPTIONS request the browser sends before certain cross-origin requests, for example with PUT or DELETE or custom headers. The server’s answer tells the browser whether the real request may be sent.

Should I add Vary: Origin to CORS responses?

Yes, whenever the Access-Control-Allow-Origin value depends on the request’s origin. Without it, a cache or CDN may serve a response with one origin’s permission to a different origin.

#Security headers#Troubleshooting#Website security
Verifică-ți propriul site — gratuit.Ce să repari pe site — și de unde să începi.
Începe gratuit

Mai multe de pe blog

Toate articolele →
Internet Solutions

Mai multe de la echipa noastră

Create de Internet Solutions. Încearcă și celelalte produse ale noastre — fiecare îți economisește timp în alt fel.

internet-solutions.net ↗
Site AI Audit
Prezentare generală a confidențialității

Acest site folosește cookie-uri pentru a-ți oferi cea mai bună experiență posibilă. Informațiile din cookie-uri sunt stocate în browserul tău și îndeplinesc funcții precum recunoașterea ta când revii pe site și ajutarea echipei noastre să înțeleagă ce secțiuni ale site-ului găsești cele mai interesante și utile.