Card 09/ 11
A Shared Cache That Serves One User's Data to Another
A CDN keeps a copy of /me for one user and hands it to the next, because the response let it.
A personal response that a shared cache is allowed to store will be served to whoever next requests the same URL. A CDN in front of GET /me with Cache-Control: public, max-age=600 hands the first user's profile to every user for ten minutes. Personal responses must be private or no-store, because a private cache belongs to one user and a shared cache to everyone.
Picture an incident the day after a CDN configuration change meant to speed up the API. Users start reporting that they see someone else's name and address on their account page. The change had added a default of public, max-age=600 to every GET.
The symptom. Users seeing other users' data, intermittently, clustered by region or by CDN node, and stopping when the cache is purged.
Why it happens. The cache key is the URL, and /me is the same URL for every user. The CDN does not know the response depends on the cookie. Shared caches refuse to store responses to requests with an Authorization header unless told otherwise, but no such rule protects cookies, and public overrides the protection for Authorization too.
What it costs. A data breach: personal data disclosed to strangers, which may have to be reported to a regulator.
What to do. Send Cache-Control: private on every response that depends on who is asking, and no-store if it is sensitive. Make that the API's default, so only responses chosen as public can be cached by a CDN. Never set public as a blanket default, and test with two accounts through the real CDN after any cache change.
← → move through sections and cards