Расколотый по диагонали кристалл на тёмном антистатическом мате: в одной половине видна миниатюрная файловая структура, из которой светящаяся стрелка символической ссылки вырывается за границу разл...


В 2026 году Anthropic раскрыла CVE-2026-39861 - уязвимость высокой степени серьёзности (CVSS 7.7, High) в Claude Code, через которую можно записывать произвольные файлы за пределами рабочей области с помощью символических ссылок. На первый взгляд - стандартный symlink following, ничего нового. Но при детальном разборе - архитектурно изящная атака: ни sandboxed-команда, ни unsandboxed-приложение по отдельности не нарушают своих ограничений, а вот их комбинация ломает всю модель изоляции. EPSS 0.71% (чуть выше медианы), единственное предусловие - prompt injection в контекстное окно агента. Красиво, если не ты жертва.

Бизнес-логика атаки: зачем ломать sandbox AI-инструмента разработки​

Claude Code - агентный инструмент, который читает, модифицирует и исполняет код в рабочем пространстве разработчика. Sandbox ограничивает исполняемые команды рамками workspace-директории. Если атакующий выходит за эти рамки, он получает:
  • Запись произвольных файлов от имени пользователя: ~/.bashrc, ~/.ssh/authorized_keys, crontab
  • Чтение секретов за пределами проекта: API-ключи, credentials, конфигурации CI/CD pipeline
  • Закрепление через persistence: cronjob, shell profile injection, git hooks
Компрометация машины разработчика - это точка входа в production. SSH-ключи, git-credentials, cloud-токены - всё это лежит в домашнем каталоге. Одна скомпрометированная dev-машина в supply chain - и атакующий получает lateral movement в корпоративную инфраструктуру без единого алерта от периметровых средств защиты. Ни один SIEM не пискнет.

Технический разбор уязвимости Claude Code CVE-2026-39861​

CWE-22 path traversal и CWE-61 symlink following: две слабости одной цепочки​

CVE-2026-39861 ассоциирована с двумя CWE, и обе принципиально важны. Это не дублирование - каждая CWE описывает свой аспект одной цепочки эксплуатации.

CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) - sandbox Claude Code ограничивает операции записи рамками рабочей директории, но не учитывает, что путь внутри workspace может быть символической ссылкой, ведущей за его пределы. Path traversal здесь реализуется не через канонические ../ последовательности, а через symlink-индirection: путь формально лежит внутри workspace, но резолвится ядром ОС за его пределы. CWE-22 исторически покрывается OWASP A01 (Broken Access Control) - и эта уязвимость характерная иллюстрация класса.

CWE-61 (UNIX Symbolic Link Following) - unsandboxed-процесс Claude Code следует по символическим ссылкам при записи файлов, не проверяя, что конечный target находится внутри workspace. Ключевой момент: два процесса с разными уровнями привилегий работают с одной файловой системой, и граница доверия проходит между ними.

Связка CWE-22 + CWE-61 формирует цепочку: sandboxed-процесс создаёт symlink (с точки зрения sandbox - легитимная операция создания файла внутри workspace), а unsandboxed-процесс переходит по нему при записи (CWE-61, отсутствие проверки реального пути). Ни один из процессов по отдельности не нарушает собственных ограничений - уязвимость возникает именно в зазоре между ними. Классический confused deputy, только deputy тут два.

Для надёжной эксплуатации атакующему нужно спровоцировать sandboxed-процесс на создание symlink - это напрямую попадает под OWASP LLM Top 10 2025 - LLM01 (Prompt Injection): crafted user input изменяет поведение LLM, обходя механизмы контроля.

CVSS 4.0 вектор: метрики и интерпретация​

Вектор: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

КомпонентЗначениеИнтерпретация
AV:NNetworkPrompt injection приходит из внешнего источника: вредоносный репозиторий, npm/pip-зависимость, PR с отравленным кодом
AC:LLowСама эксплуатация symlink following тривиальна - стандартная UNIX-операция
AT:PPresentПредусловие: нужна возможность внедрить контент в контекстное окно Claude Code
PR:NNoneАтакующему не нужна аутентификация в системе жертвы
UI:PPassiveПользователь просто работает с проектом, содержащим вредоносный контент. Никаких специальных действий не требуется
VC:H / VI:H / VA:HHighПолная компрометация конфиденциальности, целостности и доступности уязвимой системы
SC:N / SI:N / SA:NNoneПрямого воздействия на downstream-системы нет, хотя реальный lateral movement через украденные credentials - отдельная история

EPSS score: 0.0071 (0.71%), percentile 0.5031 - чуть выше медианы по всей базе CVE. Вероятность эксплуатации в дикой природе в 30-дневном окне невысока, но и не нулевая.

CISA SSVC decision: Track (мониторить). Exploitation: none (на момент оценки нет подтверждённых атак в дикой природе). Automatable: no (массовая автоматическая эксплуатация затруднена). При этом Technical Impact - total: при успешной эксплуатации компрометация полная. Характерный профиль для supply chain attack: высокий импакт при целевой атаке, но низкий потенциал для mass exploitation.

Архитектура sandbox Claude Code и точка отказа​

Модель изоляции рабочей области AI-агента​

[Применимо: любая среда, где Claude Code < 2.1.64 обрабатывает внешний/недоверенный контент]

Claude Code оперирует в модели с двумя уровнями процессов:

Unsandboxed-процесс (основное Node.js-приложение) имеет полные права текущего пользователя и выполняет файловые операции от его имени. Когда Claude Code записывает сгенерированный код в файл - это делает именно unsandboxed-процесс.

Sandboxed-процесс (исполняемые команды) ограничен рамками workspace-директории. Когда Claude Code запускает bash, python или другой интерпретатор, этот процесс не должен иметь возможности воздействовать на файловую систему за пределами рабочего пространства.

Модель безопасности строится на двух допущениях: sandboxed-процесс не может выйти за пределы workspace, а unsandboxed-процесс записывает файлы только по путям, которые логически принадлежат workspace. Нарушение любого из них ломает изоляцию. И вот тут начинается самое интересное.

Создание символической ссылки - это создание нового inode внутри workspace. С позиции sandbox, ограничивающего запись по prefix пути, это легитимная операция: новый файл появляется в разрешённой директории. Всё чисто.

Но symlink - не данные, а указатель на произвольный путь. Когда unsandboxed-процесс Claude Code позже обращается к этому пути для записи, он видит обычный путь внутри workspace и вызывает openat() без O_NOFOLLOW. Ядро прозрачно разрешает symlink, и запись уходит в target за пределами workspace. Приложение не получает никакого сигнала о том, что реальный файл находится в другом месте.

По сути - TOCTOU-паттерн (Time-of-Check-Time-of-Use): проверка (путь внутри workspace) и использование (запись по реальному пути через symlink) разнесены во времени и пространстве, выполняются разными процессами.

Цепочка эксплуатации symlink attack CVE-2026-39861​

Предусловия и ограничения​

Работает если:
  • Claude Code версии < 2.1.64
  • Атакующий может внедрить контент в контекстное окно (prompt injection через файлы проекта)
  • Пользователь активно работает с Claude Code (UI:P - passive interaction)
  • Целевая ОС: Linux или macOS (filesystem поддерживает symlinks)
Не работает если:
  • Claude Code >= 2.1.64 (патч)
  • Filesystem смонтирована с nosymfollow (Linux 5.10+)
  • seccomp-профиль фильтрует symlinkat для sandboxed-процессов
  • SELinux/AppArmor в enforcing с политикой, запрещающей symlink creation вне определённых путей

Attack flow: от prompt injection до записи произвольных файлов​

Фаза 1: Prompt Injection (LLM01:2025, Initial Access)
Атакующий размещает инструкцию в файле проекта - скрытый комментарий в .py-файле, директива в YAML-конфиге, markdown в README.md, или payload в зависимости npm/pip. Claude Code сканирует workspace, загружает контент в контекстное окно - вредоносная инструкция активируется. Пользователь ничего не замечает.

Фаза 2: Sandboxed Code Execution - User Execution (T1204, Execution)
Claude Code, следуя prompt injection, штатно исполняет команду в sandbox-контексте (T1204 - User Execution, спровоцированное вредоносным контентом). Sandboxed-процесс создаёт символическую ссылку внутри workspace, указывающую на target за его пределами.

Фаза 3: Symlink Following - Sandbox Escape (маппинг приблизительный - T1497 описывает anti-analysis evasion, точного T-кода для privilege boundary escape между процессами в ATT&CK нет)
Claude Code записывает данные по пути, который логически находится внутри workspace. Unsandboxed-процесс открывает файл, ядро разрешает symlink, запись уходит в target за пределами workspace. Пользователь не получает подтверждающий запрос - Claude Code считает операцию легитимной. С его точки зрения, всё в порядке.

Фаза 4: Arbitrary File Write - Unsandboxed File Write (Sandbox Escape)
Атакующий контролирует содержимое произвольного файла в контексте текущего пользователя:
  • ~/.ssh/authorized_keys - добавление SSH-ключа атакующего, Credentials In Files (T1552.001, Credential Access)
  • ~/.bashrc / ~/.zshrc - persistence через Hidden Files and Directories (T1564.001, Defense Evasion / Discovery)
  • ~/.gitconfig - supply chain pivot, подмена remote URL
  • Crontab - persistence через планировщик
Фаза 5: Post-Exploitation - Data from Local System (T1005, Collection)
Через ту же symlink-механику (но в обратном направлении - для чтения) атакующий получает доступ к credential-файлам, SSH-ключам, cloud-токенам, конфигурациям CI/CD. File and Directory Discovery (T1083, Discovery) позволяет маппировать файловую систему за пределами workspace.

Kill chain mapping​

ЭтапMITRE ATT&CKРоль в цепочке
Initial AccessPrompt Injection (LLM01:2025)Внедрение инструкции через вредоносный файл в проекте
ExecutionUser Execution (T1204)Sandboxed-процесс создаёт symlink по prompt injection
Defense EvasionSandbox Escape (точный T-код отсутствует в ATT&CK)Переход от sandboxed к unsandboxed через symlink bridge
Credential AccessCredentials In Files (T1552.001)Чтение/перезапись credential-файлов
CollectionData from Local System (T1005)Сбор данных за пределами workspace
DiscoveryFile and Directory Discovery (T1083)Маппинг файловой системы через symlink

Воспроизведение: минилаб и концептуальный PoC​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Ключевой индикатор: отсутствие вызова readlinkat() или lstat() между определением пути и вызовом openat(). Unsandboxed-процесс не проверяет, является ли target символической ссылкой. В пропатченной версии (>= 2.1.64) ожидается либо проверка realpath перед записью, либо блокировка symlinkat для sandboxed-процессов.

Когда техника НЕ работает​

Claude Code >= 2.1.64 - патч устраняет symlink following. Конкретный механизм патча не раскрыт в advisory, но предполагаемые варианты: запрет symlinkat через seccomp-фильтр для sandboxed-процессов, или проверка realpath() с O_NOFOLLOW при записи.

Mount option nosymfollow - доступен в Linux 5.10+, блокирует следование по symlinks на уровне VFS для конкретной точки монтирования. Если workspace смонтирован с этой опцией, ядро вернёт ELOOP при попытке открыть symlink.

gVisor / Firecracker - песочницы на уровне системных вызовов перехватывают symlinkat и могут валидировать target path до передачи в host kernel. Для dev-инструмента это перебор (overkill), но класс атак блокирует наглухо.

Контейнер с seccomp-профилем, фильтрующим symlinkat - если Claude Code запущен в Docker с ограниченным seccomp, sandboxed-процесс не сможет создать символическую ссылку. Стандартный Docker seccomp-профиль symlinkat не фильтрует - учтите.

SELinux/AppArmor в enforcing - при наличии политики, ограничивающей symlink creation для процесса Claude Code, атака блокируется на уровне MAC.

Детектирование и форензика sandbox escape​

Проактивное детектирование​

Аудит файловых операций через auditd. Правило для отслеживания создания символических ссылок:
Bash:
# /etc/audit/rules.d/claude-symlink.rules
-a always,exit -F arch=b64 -S symlinkat -F dir=/home/ -k ai_symlink_create
Это правило генерирует событие при каждом вызове symlinkat в /home/. В активной dev-среде false positive rate будет значительным - npm, pip и другие менеджеры пакетов создают symlinks штатно. Более точный подход - eBPF-программа или osquery с custom query, проверяющим, что target symlink выходит за пределы workspace.

Периодический скан workspace. Команда find <workspace> -type l -exec readlink -f {} \; покажет все symlinks и их реальные targets. Symlink, указывающий за пределы workspace - IoC, требующий расследования.

Real-time мониторинг. inotifywait -m -r -e create,moved_to <workspace> отслеживает создание файлов в реальном времени, но не различает symlink и обычный файл без дополнительной проверки через test -L.

Форензика: что проверять, если использовали уязвимую версию​

  1. Версия Claude Code: claude --version - если < 2.1.64, система была уязвима в период использования
  2. Поиск внешних symlinks: find <workspace> -type l -lname '/[I]' -not -lname '<workspace>/[/I]' - покажет ссылки, ведущие за пределы workspace
  3. Timeline анализ: mtime файлов ~/.bashrc, ~/.ssh/authorized_keys, ~/.gitconfig, ~/.config/ - совпадение mtime с временем работы Claude Code указывает на возможную эксплуатацию
  4. Логи Claude Code: директория ~/.claude/ может содержать историю взаимодействий, включая prompt injection payload, если логирование было включено
  5. Аудит SSH: grep по ~/.ssh/authorized_keys на наличие незнакомых ключей, добавленных в период использования уязвимой версии

Ограничения детектирования​

Auditd-правила на symlinkat создают шум - стандартные build-системы активно используют symlinks. Фильтрация по target path (выходит ли за workspace) невозможна на уровне auditd rules - для этого нужен eBPF-хук или постобработка логов. На macOS эквивалентный аудит через dtrace / Endpoint Security framework потребует отдельного агента. Короче, серебряной пули нет - придётся комбинировать.

Патчинг и hardening безопасности AI-инструментов разработки​

Обновление​

Основное исправление: обновление Claude Code до версии 2.1.64 или позднее. Автоматический механизм обновления уже доставил патч пользователям, не отключавшим auto-update. Ручное обновление: npm update -g @anthropic-ai/claude-code.

Defense-in-depth помимо патча​

  1. Контейнеризация Claude Code - запуск в Docker с bind-mount только workspace-директории, без монтирования домашнего каталога целиком. Ограничивает поверхность атаки даже при наличии 0-day
  2. nosymfollow mount option (Linux 5.10+) для workspace-раздела - блокирует symlink following на уровне VFS, делая класс атак нерелевантным для этой точки монтирования
  3. AppArmor/SELinux профиль для процесса Claude Code, явно запрещающий запись за пределы workspace
  4. Separation of secrets - SSH-ключи в hardware token (YubiKey/FIDO2), cloud credentials через temporary STS tokens с коротким TTL, git credentials через credential helper вместо plaintext в ~/.gitconfig
  5. Принцип минимальных привилегий для dev-среды - отдельный пользователь или namespace для работы с AI coding agents, без доступа к production-credentials

Чеклист​

  1. Проверить claude --version >= 2.1.64
  2. Убедиться, что auto-update включён
  3. find <workspace> -type l -lname '/*' по всем workspace-директориям
  4. Рассмотреть контейнеризацию AI coding tools
  5. Добавить auditd/eBPF-мониторинг symlinkat в developer-сегменте инфраструктуры
  6. Ротировать SSH-ключи и cloud-токены на dev-машинах, где использовалась уязвимая версия

Symlink-атаки на AI-агенты как класс уязвимостей​

CVE-2026-39861 - не единичный инцидент. Архитектура "AI-агент с доступом к файловой системе" воспроизводит паттерн, знакомый по setuid-бинарям и container escape: два уровня привилегий, между которыми можно построить мост через filesystem primitive. Здесь мост - symlink. В контейнерных escape - overlayfs race conditions или /proc/self/exe трюки. Суть одна: filesystem API в Unix не предоставляет атомарной операции "проверить путь И открыть файл, гарантируя неизменность пути между проверкой и открытием" - классическая TOCTOU-проблема, и ей уже лет тридцать.

AI coding agents усугубляют ситуацию: prompt injection даёт атакующему контроль над действиями sandboxed-процесса без необходимости аутентификации в системе жертвы. В классическом setuid-сценарии атакующий должен иметь shell-доступ. Здесь достаточно подготовленного файла в git-репозитории или отравленной npm-зависимости. Порог входа - ниже плинтуса.

Я проверял sandbox-реализации нескольких AI coding agents за последний год, и паттерн повторяется: разработчики ограничивают write() / open() по prefix пути, но забывают, что symlink - layer of indirection, который ядро разрешает прозрачно. Те, кто догадывается использовать realpath() перед открытием, попадают в TOCTOU: между вызовом realpath() и open() symlink можно создать или подменить. Надёжных решений два: O_NOFOLLOW в openat() плюс запрет symlinkat() через seccomp для sandboxed-процессов, или работа в отдельном mount namespace с собственным mount tree - тогда symlink физически не может указать за пределы видимого filesystem.

CISA оценила technical impact как total, но automatable - no. Массовой эксплуатации ожидать не стоит, а вот при целевой атаке на конкретного разработчика (или через supply chain - отравленную зависимость, которую клонирует тысяча проектов) импакт максимальный. Именно такой профиль - low blast radius, high damage per target - характерен для supply chain атак нового поколения, где AI-агент становится amplifier.

Рассчитывать на то, что вендоры AI-инструментов закроют все подобные примитивы патчами - стратегически наивно. Каждый новый coding agent проходит тот же цикл: "sandbox = chdir + PATH check" → CVE с symlink/hardlink/mount escape → патч → следующий filesystem primitive. Пока архитектура AI-агентов не перейдёт на capability-based sandbox (WASI, Firecracker, gVisor с полной изоляцией filesystem), symlink-атаки на рабочие области будут появляться с регулярностью нового LLM-релиза.

И если вы пишете или аудитите sandbox для AI-инструмента - начинайте не с политик на write(), а с полного перечня filesystem syscalls, создающих indirection: symlinkat, linkat, renameat2, mount. Блокируйте мост, а не трафик по нему. Если хочешь повторить подобную symlink-цепочку в контролируемой среде - задачи с filesystem-примитивами на HackerLab.pro дают именно эту практику, от race condition до контроля записи.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab