skip to content

When does `Access-Control-Allow-Origin: *` leak data, given the same header reveals nothing on a fully public resource?

level: seniorimportance: must knowfreq 60%

answer

  1. the grant is about reading only
  2. nothing new on already-public data
  3. network position as the credential
  4. the employee's browser is the reader
  5. ask what was protecting it before

basics

~20 s

It leaks whenever the resource's only protection is the caller's network position. On data any client could already retrieve anonymously the wildcard reveals nothing new; on an internal service it converts every employee's browser into a reader on the attacker's behalf.

solid answer

~50 s

The wildcard says one thing: script on any page may read this response. On a resource that any client on the internet could already fetch anonymously, that adds nothing an attacker did not have — they could request it directly from their own machine. The header becomes a breach when what was keeping the data private is **where the caller is**, not who they are: a service reachable only from inside a network, or one that authorises by address. There, the same-origin rule was the thing stopping a page in an employee's browser from reading a response that browser could fetch, and the wildcard removes it. The specification is explicit that the CORS protocol must not be relied on for data protected that way. The judgement is therefore about the resource, not the header: ask whether "public" means public from everywhere or only from inside.

code

http · 7 lines
http
GET /metrics/db-primary HTTP/1.1
Host: ops-dashboard.internal
Origin: https://attacker.test

HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: *

go deeper

for a junior

Remember that this header decides only whether script may read a response. It does not decide whether the request is sent or whether the service answers it.

for a middle

Explain why the same header is harmless on anonymous public data and dangerous on an internal service, by naming what was protecting the resource beforehand.

for a senior

Walk the internal case end to end: the victim's browser is already inside the network, the request looks ordinary in the logs, and the grant is what turns a reachable service into a readable one.

for a principal

Treat it as a question about resource classification rather than header hygiene. An estate-wide rule banning the wildcard buys little; knowing which endpoints rely on network position buys the audit.

## What the wildcard actually says `Access-Control-Allow-Origin: *` is a grant, not a setting. It states that script running on a page of **any** origin may read this response. It changes nothing about who can send a request, nothing about whether the service processes it, and nothing about the network the service sits on. It is purely an instruction to browsers about what to release to a calling script. That narrowness is what makes the judgement possible at all: the header is the same everywhere, and its consequence depends entirely on what was protecting the resource beforehand. ## Where it reveals nothing If the resource is retrievable anonymously by any client on the internet — a published schedule, a price list, a static asset served without a session — then the attacker already has the data. They do not need a victim's browser to fetch something their own server can fetch. Adding the wildcard hands script a convenience; it hands the attacker nothing they lacked. This is the half that is usually missed, and it is why blanket advice to "never use the wildcard" is wrong. On genuinely public data the wildcard is the correct answer, and the alternative — computing a per-caller grant — is strictly worse, because that is exactly the machinery that turns into reflection. ## Where the same header is a breach The wildcard becomes a data leak precisely when the resource's protection is **the caller's network position**: - A service reachable only from inside a corporate network or a private network segment. - A service that authorises by source address rather than by a credential the caller presents. - A device or administrative interface exposed on a local network and never on the internet. In all three, the reason the data was safe is that the attacker's machine cannot reach the service. But an employee's browser can, and it will send a cross-origin request to anything a page tells it to. Until now the same-origin rule was what stopped the attacker's page from **reading** the reply; the wildcard is the server volunteering to remove that. The browser becomes a reader inside the network, working on the attacker's behalf, and nothing in the network path sees anything unusual — the request came from an employee's machine, as internal requests do. This is why the specification says plainly that the CORS protocol must not be used to protect data whose defence is address-based authentication or a firewall. The protocol was invented to hand out cross-origin reads; asking it to withhold them is asking it to do the opposite of its job. ## Deciding it in practice | The resource | Wildcard verdict | |---|---| | Anonymous, retrievable by anyone on the internet | Reveals nothing new; the wildcard is the correct grant | | Anonymous, but reachable only from inside a network | A breach; the network position was the credential | | Authorised by source address | A breach, for the same reason | | Authorised by a credential the caller presents | Different question entirely — the grant interacts with credentialed mode, which has its own rules | The useful test is one sentence: **would an unauthenticated client anywhere on the internet already get this response?** If yes, the wildcard costs nothing. If no, ask what made the difference, and if the answer is "where the caller was", the wildcard is the whole attack. ## Two things this does not change 1. **Reachability.** The header does not expose a service to the internet, and removing it does not un-expose one. An internal service with the wildcard is still unreachable from the attacker's own machine. 2. **Non-browser clients.** Anything that does not implement the browser's rule was never restricted by it and is not affected either way. The whole mechanism is a bargain between a server and browsers, on behalf of users. The operational consequence is that discovering this problem means looking at the resource, not at the header. A sweep that flags every wildcard produces a long list of correct answers and a few breaches; a sweep that asks which wildcard-granting endpoints are unreachable from outside produces the short list that matters.

  • Does the wildcard grant make an internal service reachable from the internet?
    No. Reachability is unchanged: the attacker's own machine still cannot open a connection to it. What changes is that a browser which *can* reach it — a visitor's, sitting inside the network — will now release the response to script on a page the attacker controls. The reader was always there; the grant is what lets the attacker read over its shoulder.
  • Which endpoints would you actually look at first when auditing wildcard grants across an estate?
    The ones whose responses an anonymous client on the internet could not already obtain. Enumerating every wildcard produces mostly correct answers; the short list worth reviewing is the intersection of "grants the wildcard" and "is not reachable, or not authorised, from outside", because that intersection is exactly where network position was doing the protecting.
  • What is the honest argument for keeping the wildcard on a public endpoint?
    The alternative is to compute a grant per caller, and that machinery is what degrades into echoing the arriving origin once the caller list stops being knowable. On data that is genuinely public from everywhere, the wildcard is a fixed, reviewable value that cannot widen, which makes it the safer of the two.

Propping open the lobby door of a building anyone may walk into changes nothing. Propping open an interior door, whose only lock was that you had to already be inside, changes everything.

saying these in an interview costs you the question

  • A wildcard grant is safe because the service is not on the internet.
  • Access-Control-Allow-Origin: * is always a vulnerability.
  • Adding the wildcard makes the service reachable from the internet.
  • A firewall protects the service, so the browser's rules do not matter.
  • Public data becomes sensitive as soon as a wildcard grant is added.