Современные веб-архитектуры любят кэширование. Их много: на уровне приложения, на уровне CDN/прокси — и каждый живёт своей жизнью.
Но стоит конфигурации чуть разойтись, и начинается магия: разные кэши начинают хранить разные версии одного и того же ответа.
Рассмотрим пример приложения на Drupal, которое использует два кэш-заголовка:
X-Drupal-Cache (кэш на уровне приложения) и X-Cache (кэш на уровне прокси/CDN). Когда страница успешно закэширована, эти заголовки показывают статус HIT; если нет — MISS.Первый запрос возвращает
X-Cache: HIT, что подтверждает кэширование страницы, хотя заголовок X-Drupal-Cache показал MISS:GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 37531
X-Drupal-Cache: MISS
X-Content-Type-Options: nosniff
Cache-Control: public, max-age=0
Vary: Cookie,Accept-Encoding
Age: 6
X-Cache: HIT
Когда мы добавляем
Authorization в запрос, оба заголовка возвращаются со значением HIT:GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Authorization: test
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 37531
X-Drupal-Cache: HIT
X-Content-Type-Options: nosniff
Cache-Control: public, max-age=0
Vary: Cookie,Accept-Encoding
Age: 12
X-Cache: HIT
Когда снова удаляем
Authorization из запроса, статус X-Drupal-Cache: HIT сохраняется:GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 37531
X-Drupal-Cache: HIT
X-Content-Type-Options: nosniff
Cache-Control: public, max-age=0
Vary: Cookie,Accept-Encoding
Age: 5
X-Cache: HIT
Это указывает на то, что были задействованы два разных механизма кэширования, позволившие сохранять ответы в кэше при разных условиях.
🚨 Что это значит?
Система пытается разделять авторизованных и неавторизованных пользователей, но механизм кэширования игнорировал заголовок
Authorization. В итоге приватный ответ мог попасть в публичный кэш → любой юзер получит чужой контент.По сути, это Cache Deception. Если на проекте несколько уровней кэша и они по-разному трактуют заголовки — явный признак наличия бага:
💡 Всегда проверяй, какие заголовки влияют на кэширование (
Authorization, Cookie, Host и т.п.)💡 Сравнивай ответы приложения и CDN
💡 Ищи «залипшие»
HIT-ы там, где должны быть MISS
