Web Cache Deception: как кеш превращается в утечку данных
1. Что такое кеш и зачем он нужен?
Представьте, что вы заходите на любимый сайт. Каждый раз, когда вы открываете страницу, сервер должен обработать ваш запрос, собрать данные и отправить их вам. Если сайт популярный, тысячи пользователей одновременно запрашивают одни и те же страницы, создавая нагрузку на сервер.
Чтобы ускорить работу сайта и снизить нагрузку, используют кеш. Это временное хранилище, где сохраняются копии страниц, изображений и других файлов. Когда вы запрашиваете страницу, сервер может отдать её из кеша, вместо того чтобы генерировать заново.
Где встречается кеширование?
- Браузерный кеш (сохраняет картинки, CSS, JS, чтобы страницы грузились быстрее)
- CDN-кеш (например, Cloudflare, Akamai — хранят копии сайтов на серверах по всему миру)
- Прокси-кеш (Varnish, Nginx — ускоряют загрузку на стороне сервера)
Но если кеш настроен неправильно, он может выдать ваши личные данные посторонним людям. Именно так работает атака Web Cache Deception.
2. Что такое Web Cache Deception (WCD)?
Web Cache Deception (WCD) — это уязвимость, которая позволяет злоумышленнику "обмануть" кеширующий сервер и заставить его сохранить конфиденциальные данные (например, вашу личную страницу), а потом получить к ним доступ.
Как это работает?
1. Вы заходите на сайт example.com/account — там ваши личные данные.
2. Злоумышленник отправляет вам ссылку:
example.com/account/style.css
(обратите внимание на .css в конце — это важно!)
3. Сервер видит, что файл .css обычно статический, но если страница account не проверяет расширение, он может отдать HTML-страницу вместо CSS.
4. Прокси-сервер (например, Cloudflare) думает: "Ага, это CSS-файл, его можно закешировать!" — и сохраняет вашу личную страницу в кеше.
5. Теперь любой, кто зайдет по ссылке example.com/account/style.css, получит ваши данные из кеша!
3. Реальный пример из Bug Bounty
Баг-репорт: Web Cache Deception
Web Cache Deception leading to sensitive data exposure
15.03.2023
Шаги воспроизведения:
1. Авторизуйтесь на example.com/profile 2. Откройте в браузере: example.com/profile/nonexistent.css 3. Сервер возвращает HTML-страницу профиля (статус 200). 4. Обновите страницу несколько раз — ответ закеширован (проверка через curl -I показывает X-Cache: HIT). 5. Выйдите из аккаунта и откройте ту же ссылку — вы видите чужой профиль!
curl -i https://example.com/profile/nonexistent.css
HTTP/1.1 200 OK X-Cache: HIT # Файл закеширован! Content-Type: text/html # Должен быть text/css! <html>... Личные данные пользователя ...</html>
Уровень опасности: 🔴 High (утечка персональных данных)
- Добавить Cache-Control: no-store для приватных страниц. - Не кэшировать ответы с Set-Cookie. - Блокировать запросы с подозрительными расширениями к динамическим страницам.
4. Web Cache Deception глазами хакера
Теперь, когда мы разобрались с теорией, давайте посмотрим на ситуацию с точки зрения атакующего — как именно можно эксплуатировать Web Cache Deception, используя дисбаланс в интерпретации "разделителей" (delimiter discrepancies).
Что такое "разделитель" (delimiter)?
Разделители — это специальные символы в URL, такие как ?, #, /, ; и их URL-кодированные формы (%3F, %23, %2F и т.д.).
Они используются для структурирования URL — например, ? отделяет путь от параметров, # указывает якорь на странице.
Проблема возникает, когда кеш и основной сервер обрабатывают эти символы по-разному:
- Один может декодировать
%3Fв?и обрезать путь. - Другой может оставить
%3Fкак есть и считать весь путь частью запроса.
Как это использует хакер?
Цель:
Обмануть кеш, заставить его сохранить приватную страницу как будто это обычный статический ресурс — .css, .js, .ico.
Пример:
- Уязвимая страница:
https://example.com/profile - Хакер отправляет жертве ссылку:
https://example.com/profile%3Ftest.js %3F=?(URL-кодированный символ)- Для кеша это может выглядеть как
.jsфайл — значит можно кешировать! - А сервер, наоборот, видит просто
/profileи отдает HTML-страницу с личными данными. - Жертва переходит по ссылке (будучи авторизованной)
— сервер отдает личную страницу,
— кеш сохраняет её. - Теперь любой пользователь, даже без логина, может открыть ту же ссылку и получить чужую HTML-страницу из кеша.
Что и как тестировать
Чтобы находить такие уязвимости, хакер:
- Находит динамическую страницу (например,
/account,/dashboard,/user/settings). - Добавляет к URL кодированный разделитель и статическое расширение:
/account%3Ffake.css /dashboard%23test.js /user/settings%2Ficon.ico - Проверяет:
Делимитеры, которые стоит протестировать
%00, %09, %0A, %0D, %2F, %3F, %23, ;, |, `, ~
Что именно кешируется?
- Кеш всегда кеширует ответ, не сам запрос.
- Если ответ выглядит как статический файл, и нет запрета на кеширование (Cache-Control) — он попадёт в кеш.
- А если при этом ответ содержит приватные данные, то — мои поздравления! — уязвимость найдена.
Почему это опасно
Разные системы — кеш, прокси, CDN и бэкенд — могут:
- По-разному декодировать URL.
- По-разному обрабатывать разделители.
- Решать, кешировать или нет — по собственным правилам.
Это расхождение и открывает хакеру окно возможностей.
Пример
curl -i https://target.com/account%3Flol.css
HTTP/1.1 200 OK X-Cache: HIT Content-Type: text/html <html>... Личная информация ...</html>
Вывод
- Никогда не полагайтесь на расширение в URL.
- Всегда проверяйте заголовки кеша.
- Если видите подозрительное поведение при запросе вида
/private%3Ffake.css— это может быть Web Cache Deception.