Skip to content

encoding

Stored and reflected

The same defect, with the distance between the input and the damage changed.

Reflected is the one that is easy to see: a value arrives in a request and comes back in that request's response. You can send it and watch it return.

Stored is the same defect with a gap in the middle. A value arrives on Tuesday, is written down, and is rendered on Wednesday — to somebody who never sent it, which is what makes it worth more to an attacker and harder to notice in review.

  • PATCH /orders/1001

    Nothing visible happens. The response is the same shape it always is.

  • GET /orders/1001/page

    And now it is on the page, on a request that carried nothing.

The engine tracks that gap rather than guessing at it. A value that arrives in a request is remembered for the rest of the session, and its provenance is marked as stored once it has survived a request — so 'these bytes came from an earlier request' is something the app knows rather than infers.

That distinction is why the two have separate classes here. Naming one when the exercise is about the other is not quite wrong, and it is not right either: the fix is the same and the blast radius is not.

This build

shop.example.com

Nothing sent yet. Every request goes to the application in this tab and nowhere else.