Обман веб-кэша — когда конф. данные становятся статикой

Всем привет. На выходных решил немного вернуться к тому, с чего начинался мой путь в ИБ. Кроме книг, это были лаборатории PortSwigger.

В тот период я довольно плотно практиковался и закрыл больше 50% лаб, прежде чем пошёл по тех. интервью и в итоге попал в AppSec в окко.

И вот недавно я добил направление, которое ещё с прошлого года висело у меня не закрытым, — уязвимости, связанные с веб-кэшем.

Решил сделать 2 поста: • Web Cache Deception — обман веб-кэша • Web Cache Poisoning — отравление веб-кэша

Сегодня первая часть — про обман веб-кэша. На скрине к посту как раз оставлю решённую expert-лабу по этой теме.

━━━━━━━━━━ Что такое веб-кэш ━━━━━━━━━━

Если совсем просто, кэш нужен для того, чтобы не гонять один и тот же статический контент с сервера каждый раз.

Например: • .css • .js • изображения • favicon.ico • файлы из /static, /assets, /images

Такие ресурсы часто отдаются через CDN или промежуточный cache server. Это снижает нагрузку на backend и ускоряет доставку контента пользователю. Но проблема начинается там, где кэш и основной сервер по-разному понимают один и тот же URL.

━━━━━━━━━━ Что такое Web Cache Deception ━━━━━━━━━━

Web Cache Deception — это уязвимость, при которой атакующий заставляет кэш сохранить приватный динамический ответ как будто это обычный статический файл.

То есть сервер может думать: ➤ “это /profile, надо отдать данные пользователя”

А кэш может думать: ➤ “это /profile?wcd.css, похоже на статику, надо сохранить”

В итоге жертва переходит по специально подготовленной ссылке, её приватный ответ попадает в кэш, а атакующий потом запрашивает этот же URL и получает уже закэшированную конфиденциальную информацию.

Главная суть здесь не в “магии кэша”, а в расхождении между тем: • как URL интерпретирует origin server • и как этот же URL интерпретирует cache/CDN

━━━━━━━━━━ Основные направления эксплуатации ━━━━━━━━━━

PortSwigger выделяет несколько больших подходов, и я бы кратко описал их так:

Правила статических расширений Когда кэш сохраняет всё, что заканчивается на .css, .js, .ico и т.д.

Правила статических директорий Когда кэш доверяет путям вроде /static, /assets, /scripts, /images.

Правила конкретных имён файлов Когда кэш ориентируется на robots.txt, index.html, favicon.ico и похожие файлы.

И во всех этих случаях ключевая мысль одна: нужно найти URL, который backend воспримет как динамический endpoint, а кэш — как статический ресурс.

━━━━━━━━━━ Как это искать ━━━━━━━━━━

Мой короткий флоу после лаб выглядит так: • найти endpoint с чувствительными данными • посмотреть, кэшируются ли статические ресурсы • искать расхождения в обработке URL • тестировать расширения, разделители и нормализацию пути • проверять заголовки вроде X-Cache, Age, Cache-Control • сравнивать первый и повторный запрос

Пример логики я приводил выше с /profile?wcd.css

━━━━━━━━━━ Как защищаться ━━━━━━━━━━

Базовые меры защиты выглядят так: • динамические ответы помечать Cache-Control: no-store или private • не давать CDN переопределять Cache-Control для приватных данных • проверять, что Content-Type ответа соответствует расширению в URL • включать защиту CDN от cache deception, если она есть • не кэшировать ответы, зависящие от cookies, сессии или авторизации • проверять, что origin server и cache server одинаково интерпретируют URL • аккуратно настраивать правила для /static, /assets и файловых расширений

━━━━━━━━━━ Мини-итог ━━━━━━━━━━

Web Cache Deception я раскрыл не полностью и более подробно можно ознакомиться по ссылке ниже, напрямую от PortSwigger ➥ https://portswigger.net/web-security/web-cache-deception

Во второй части я разберу уже Web Cache Poisoning там кэш используется не для вытаскивания приватного ответа, а для подмены того что потом увидят другие пользователи.

#AppSec #PortSwigger #BugBounty #Pentest #WebSecurity #CyberSecurity

Обман веб-кэша — когда конф. данные становятся статикой | Сетка — социальная сеть от hh.ru