Авторские курсы Михаила Тарасова

XSSI на SPA-фреймворках: Как фронтенд отдаёт твои секреты на блюдечке

XSSI на SPA-фреймворках: Как фронтенд отдаёт твои секреты на блюдечке

Эй, бро, если думаешь, что SPA (Single Page Application) на React, Vue или Angular — это крепость, то у меня для тебя новости. Эти фреймворки, как твоя бывшая: выглядят красиво, а внутри — дыры. Сегодня разберём XSSI (Cross-Site Script Inclusion), технику, где фронтенд сам отдаёт твои данные злоумышленнику, пока ты думаешь, что «CORS всё прикрыл». Погнали копать.

Точка входа

Что вижу: SPA-фреймворки часто подгружают JSON-данные через <script>-теги или прямые GET-запросы на эндпоинты /api/user-data, где лежат вкусные токены, PII (Personally Identifiable Information) или другая чувствительная инфа. Если сервер не настроен на проверку Origin или отдаёт JSON без защиты от XSSI, то любой сайт может подгрузить этот скрипт и спарсить данные.

Как поймал: Инструмент — Burp Suite + простая заготовка HTML-страницы для теста (вот тебе код ниже). Метод — инспекция сетевых запросов через devtools, ищу эндпоинты, которые отдают JSON без заголовков X-Content-Type-Options: nosniff или с кривым CORS.

Чем пахнет: Класс — утечка данных (Data Exposure), вероятность — 8/10, потому что 90% SPA-разрабов забывают, что JSON можно просто подгрузить через <script src> с чужого домена.

Че почем

Эксплойт: Вот тебе минимальный PoC, чтобы проверить XSSI на таргете. Создаём HTML-страничку на своём сервере (или локально, если ты параноик):

Если в консоли или на твоём сервере evil.com появились данные с target.com — поздравляю, ты только что украл пользовательскую сессию или токен.

Обход защиты: Если CORS стоит, но эндпоинт отдаёт JSONP (JSON with Padding) или сервер не фильтрует заголовки, пробуем подменить Origin через:

Или используем старый добрый трюк с <script src> — многие сервера до сих пор не понимают разницу между nosniff и «похер на всё».

Доказательство: Открывай консоль браузера, смотри, как JSON с target.com парсится на твоём evil.com. Видишь строку "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."? Это не мем, это твой доступ в админку. Скриншот себе на память, братан.

Советы

3 вектора для добивания:

  1. Проверь другие эндпоинты: Если /api/user-data прикрыли, фаззи через ffuf другие пути типа /api/settings/api/profile/debug.json — разрабы любят оставлять мусор.

  2. Смотри на JSONP: Если эндпоинт поддерживает callback параметр (/api/data?callback=myFunc), ты можешь напрямую вызвать функцию на своём сайте. Пример: <script src="https://target.com/api/data?callback=stealData"></script>.

  3. Ищи старые версии фреймворков: Если SPA на старом Angular (<1.6) или React с кривыми библиотеками, там могут быть встроенные XSSI-дыры. Погугли CVE, например, CVE-2018-6341 для старых Angular-версий, и эксплойты на exploit-db.com.

План атаки:

  1. Сканируй сайт на предмет открытых JSON-эндпоинтов через nuclei -t cves -u target.com.

  2. Если находишь что-то вкусное, создавай PoC (как выше) и проверяй, можно ли спарсить данные.

  3. Если данные уходят на твой сервер, готовь отчёт для баг-баунти или используй токены для дальнейшего пентеста (например, через jwt_tool -I -pc role -pv admin).

Бонус: Проверь robots.txt и sitemap.xml на наличие /api-эндпоинтов или старых бэкапов. Если фронт на React — смотри build.js или bundle.js на предмет хардкодных токенов. И да, если видишь Docker в хедерах — сразу пробуй curl --unix-socket /var/run/docker.sock http://localhost/images/json. Это тебе подарок от деда.

Если всё глухо — иди спать, бро. Или попробуй залить reverse-shell через EXIF картинки в профиль. Да, это низко. Да, это работает. Иначе — пиздец, иди учи Rust, братан.

Мои курсы