skip to content

A loyalty scheme's brand hosts share one registrable domain; one brand host is compromised — how does that break a plain double-submit CSRF check elsewhere?

level: seniorimportance: should knowfreq 48%

answer

  1. cookies lack integrity between siblings
  2. the parent-scoped Domain write
  3. the victim host cannot tell them apart
  4. the attacker picks the value, not guesses it
  5. both halves under attacker control

basics

~20 s

Cookies carry no integrity guarantee between hosts of one registrable domain. A compromised brand host can set a cookie scoped to the shared parent, so the victim host cannot tell it from its own — and the attacker then controls both halves of the pair.

solid answer

~40 s

The plain pattern assumes only your servers can write into your cookie namespace, and that assumption is false across sibling hosts. Any host under the shared registrable domain can send a `Set-Cookie` with `Domain` pointed at the parent, and RFC 6265bis says plainly under *Weak Integrity* that the receiving host cannot distinguish such a cookie from one it set itself. So an attacker who controls — or merely gets script execution on — one brand host plants a value of his choosing, then causes the victim's browser to submit that same known value. Where the submitted copy is a form field, a plain cross-site form finishes the job with no script on the victim host at all. The comparison passes, because it only ever checked that two strings were equal.

code

http · 4 lines
http
HTTP/1.1 200 OK
Host: promos.brand.example
Set-Cookie: csrf=chosen-value-1234; Domain=brand.example; Path=/
Content-Type: text/html;charset=utf-8

go deeper

for a junior

The point to take away: another host sharing your domain name can write cookies your host will read, and a check that only compares two values cannot tell.

for a middle

Explain how the Domain attribute lets a sibling's response reach your host's cookie jar, and why the attacker picking the value defeats unpredictability.

for a senior

Walk the forgery end to end, say which carriage of the submitted copy makes it cheap, and name the ambiguous duplicate-name symptom an operator would actually see first.

for a principal

Recognise that this makes every host under the registrable domain part of your security perimeter, including ones another team or a partner runs.

## The property being exploited The plain double-submit check verifies that two strings are equal. It therefore rests, silently, on a second assumption nobody writes down: **that only your own servers can put a cookie into the namespace your host reads.** Across a shared registrable domain that assumption does not hold. The cookie layer was never an origin-scoped store. A response from any host under the registrable domain may carry a `Set-Cookie` with the `Domain` attribute pointed at the shared parent, and the resulting cookie is then sent to every host under it. RFC 6265bis states the consequence directly in its *Weak Integrity* security consideration: a host in that position can set a cookie that the victim host **will be unable to distinguish from a cookie it set itself**. There is no marker on the wire for who wrote it. A multi-brand loyalty scheme is the shape that makes this concrete. Each brand runs its own host under one shared parent domain so that a single account accrues points everywhere. The team chose the stateless check specifically so no brand's servers hold session state for the others — and in doing so drew its trust boundary around the whole registrable domain instead of around one host. ## What the attacker needs, and what he does not He needs **one** of the sibling hosts to do his bidding for the length of one response. That can be a full compromise, an abandoned marketing host, a partner's staging box, or nothing more than script execution inside a page on that host — enough to cause one cookie to be written with a parent-scoped `Domain`. He does **not** need: - any access to the victim brand's servers, code or database; - to read anything out of the victim's own cookies — he does not need to learn the real value, because he replaces the question with a value he chose; - to defeat unpredictability. Unpredictability protects a value he must *guess*. It does nothing about a value he gets to *pick*. ## Walking the forgery through 1. The victim, logged in to the loyalty account, visits any page — or is served any subresource — that reaches the compromised sibling host. 2. That host answers with `Set-Cookie: csrf=chosen-value; Domain=<shared parent>; Path=/`. The browser stores it and will attach it to requests bound for the victim brand's host. 3. The attacker's page then causes a state-changing request at the victim host, carrying `chosen-value` as the submitted copy. 4. The victim host reads the cookie copy, reads the submitted copy, sees `chosen-value` on both sides, and accepts the write. Step 3 is where the **carriage of the submitted copy** decides how cheap the attack is: | Where the submitted copy travels | What the attacker must add | |---|---| | A hidden field in an `application/x-www-form-urlencoded` body | Nothing beyond a hostile page with a form — no script on the victim host, and the form may be served from anywhere at all | | An author-set request header | Script running somewhere the victim host's own cross-origin permissions already cover — which, in a multi-brand estate, is very often a sibling brand | | Either, because the server accepts both | The cheaper of the two, so the header-only hardening is worth nothing here | There is one further wrinkle worth expecting in the wild: the planted parent-scoped cookie and the host's own cookie can both exist **with the same name**, and both are then sent on the same request. The server does not see one overwrite the other; it sees an ambiguous `Cookie` header and typically reads whichever copy it meets first. From the defender's side this presents as an intermittent, unreproducible failure — which is a diagnostic tell worth remembering. ## Why a different port or scheme is not a boundary either The same specification notes that cookies are not isolated by **port** and not isolated by **scheme** in the way origins are. A sibling reachable on another port, or the plaintext version of a host, is not outside the perimeter of this defence. If your mental model of the trust boundary is the origin tuple, the cookie layer is a coarser thing than you think it is, and the double-submit pattern inherits that coarseness whole. ## What actually fails, stated precisely Not "the token leaked". Not "the site got hacked". The failure is: **the comparison verified equality between two values both of which the attacker supplied**, because nothing in the pair tied it to the victim's session and nothing in the cookie layer tied it to the host that issued it. Every repair for this leaf is an answer to exactly that sentence.

  • Why does making the value unpredictable not help here?
    Unpredictability defeats an attacker who has to guess the value your server issued. This attacker never guesses: he writes a cookie carrying a value he chose, so the strength of your random source is irrelevant to the pair he submits. The defect is integrity, not entropy.
  • The compromised host is only a marketing site with no access to the loyalty database — why does that not limit the damage?
    Because the attack does not use that host's data or privileges. It uses its ability to emit one `Set-Cookie` with a parent-scoped `Domain`. Every host under the shared registrable domain has that ability, whatever it is otherwise allowed to reach.
  • Would rotating the value on every response close this?
    No. Rotation changes what your server issues; the attacker's planted cookie is not your server's issue. His pair still matches itself, and a check that compares only the two submitted halves accepts it on any schedule of rotation.
  • How might this present to an operator before anyone suspects forgery?
    As intermittent, unreproducible rejections. The planted cookie and the host's own cookie share a name and both travel on the request, so which copy the server reads varies, and legitimate submissions start failing for a subset of users with no pattern in the application logs.

A shared mailroom: every tenant in the building can drop an envelope into your pigeonhole, and all of them arrive stamped with the building's address. You cannot tell from the envelope which tenant wrote it.

saying these in an interview costs you the question

  • Says a strong random value makes cookie injection irrelevant.
  • Assumes a cookie set by another host is visibly distinguishable from ours.
  • Thinks the attacker needs to read the victim's real value first.
  • Treats hosts of one registrable domain as isolated from each other.
  • Claims only a full compromise of the sibling host enables this.
  • Believes a different port or scheme puts a sibling outside the cookie perimeter.