Что такое sandbox escape для AI-агента и как защититься?
Краткий тезис
Sandbox escape — это атака, при которой злоумышленник заставляет AI-агента выйти за пределы изолированной среды выполнения (sandbox) и выполнить произвольные команды на хост-системе. Для агентов, имеющих доступ к shell или системным вызовам, это означает полный компрометацию сервера. Защита строится на принципе минимальных привилегий, строгой изоляции (контейнеры, seccomp, AppArmor), allowlist разрешённых команд и обязательном подтверждении опасных действий человеком (human‑in‑the‑loop).
1. Термин: Sandbox и Sandbox escape
Sandbox — это изолированная среда, в которой агент может выполнять код или команды, не имея доступа к ресурсам хост‑системы (файловая система, сеть, процессы). Sandbox может быть реализован контейнером (Docker, podman), виртуальной машиной, chroot‑окружением или специальной библиотекой (например, gVisor, Firecracker).
Sandbox escape — выход за пределы sandbox. Если агент получает способность выполнить системный вызов или команду, которая воздействует на хост, это и есть escape. Например:
rm -rf /из контейнера, если не установлены ограничения на файловую систему.- docker run --privileged -v /:/host ... — запуск нового контейнера с доступом ко всем ресурсам хоста.
- Использование уязвимости в ядре (CVE) для повышения привилегий внутри контейнера и доступа к хост‑процессам.
2. Почему AI-агент особенно уязвим к sandbox escape
AI‑агенты часто получают доступ к shell (bash, powershell) для выполнения команд в инфраструктуре — это удобный интерфейс для автоматизации. Однако такая возможность превращается в брешь, если злоумышленник может внедрить вредоносную команду через prompt injection или манипуляцию входными данными.
Основные причины:
- Prompt injection — агент интерпретирует часть вредоносного промпта как инструкцию к выполнению shell‑команды.
- Неполная валидация выходов — агент может сам сгенерировать команду, которая приводит к escape.
- Широкий доступ к API — агент имеет вызовы для работы с файловой системой, сетью, процессами, что позволяет исследовать хост.
Пример типовой атаки:
- Пользователь отправляет запрос: «Выполни ls, а затем cat /etc/passwd».
- Агент (с помощью LLM) преобразует запрос в shell‑команду
ls; cat /etc/passwd. - Если sandbox не блокирует чтение /etc/passwd, данные утекают.
3. Типичные методы sandbox escape для AI-агентов
| Метод | Описание | Пример команды |
|---|---|---|
| Прямой доступ к файловой системе хоста | Монтирование хостовой ФС внутрь контейнера, если агент может выполнить mount или docker run. | docker run -v /:/host busybox cat /host/etc/shadow |
| Использование утилит с привилегиями | Запуск sudo, su или установка SUID‑бита через агента. | sudo rm -rf / |
| Эксплуатация уязвимостей ядра | Агент может запустить бинарник, который использует известную CVE для выхода из namespace. | ./exploit (загруженный в sandbox) |
| Взаимодействие с Docker socket | Если docker.sock доступен, агент может управлять контейнерами хоста. | curl --unix-socket /var/run/docker.sock http://localhost/containers/json |
| Символические ссылки / proc‑fs | Чтение /proc/1/root для доступа к корневой ФС хоста из контейнера. | cat /proc/1/root/etc/shadow |
Каждый из этих методов успешно эксплуатировался в реальных атаках на AI‑агентов (в т.ч. в CTF‑задачах).
4. Принципы защиты от sandbox escape
4.1 Никогда не давать агенту прямой доступ к shell
Вместо shell используйте изолированные API — функции, которые принимают строго типизированные аргументы. Например, не вызывать os.system(user_input), а реализовать метод list_directory(path), который внутри использует os.listdir с валидацией path.
4.2 Запускать агента в контейнере с read‑only файловой системой
Установите политику readOnlyRootFilesystem: true в Kubernetes (или --read-only для Docker). Агент сможет писать только в смонтированные tmpfs‑тома.
4.3 Использовать профили seccomp и AppArmor
- seccomp (secure computing mode) — ограничивает системные вызовы, доступные процессу. Например, запретить mount, ptrace, clone с флагами создания нового namespace.
- AppArmor — профиль может запретить чтение файлов за пределами определённых директорий.
Пример seccomp‑политики (фрагмент):
{
"defaultAction": "SCMP_ACT_ERRNO",
"syscalls": [
{"names": ["read", "write", "open", "close", "stat", "fstat", "lstat", "getdents"], "action": "SCMP_ACT_ALLOW"},
{"names": ["mount", "umount", "pivot_root", "chroot"], "action": "SCMP_ACT_ERRNO"}
]
}
4.4 Allowlist команд
Разрешите только конкретный набор команд с фиксированными аргументами. Например, для веб‑сервера: ls /data, cat /data/*.txt. Все остальное блокируется.
4.5 Human‑in‑the‑loop (подтверждение человеком)
Любая команда, признанная подозрительной (изменение файловой системы, запуск новых процессов, работа с сетью), должна быть отправлена на одобрение оператору. Это возможно реализовать через механизм approval в LangChain или открытие диалогового окна в UI.
5. Технические средства изоляции агента
5.1 Docker / Podman
Используйте образы без оболочек (distroless, scratch) и отключайте возможность запуска shell:
FROM alpine:latest AS builder
# build...
FROM gcr.io/distroless/base
COPY --from=builder /app /app
ENTRYPOINT ["/app/agent"]
5.2 gVisor
gVisor — это изолированное ядро пользовательского пространства, которое обрабатывает системные вызовы. Даже если агент найдёт escape для контейнера, он не сможет покинуть sandbox gVisor.
5.3 kata‑containers / Firecracker
Запуск каждого агента в отдельной VM даёт максимальную изоляцию. Подходит для сценариев с высокими требованиями безопасности.
5.4 Безопасные сэндбоксы для shell
Если shell необходим, используйте библиотеки вроде subprocess с ограниченными путями и запретом на опасные символы (например, ;, |, \n). Обязательно используйте shell=False и передавайте аргументы списком.
6. Пример: реализация безопасного выполнения команд (Python)
Опасный вариант (уязвим к sandbox escape):
import subprocess
def execute_user_command(user_input: str):
# ❌ shell=True позволяет инъекцию через ; или |
subprocess.run(user_input, shell=True)
Безопасный вариант (allowlist + изоляция):
import subprocess
ALLOWED_COMMANDS = {
"ls": ["/data"],
"cat": ["/data/*.txt"],
}
def execute_whitelisted(command: str, args: list[str]) -> str:
if command not in ALLOWED_COMMANDS:
raise PermissionError(f"Command '{command}' is not allowed")
# запускаем без shell, аргументы передаём списком
result = subprocess.run([command] + args, capture_output=True, shell=False)
return result.stdout.decode()
# Пример вызова
print(execute_whitelisted("ls", ["-la", "/data"]))
Дополнительно: запуск в Docker из Python
import docker
client = docker.from_env()
container = client.containers.run(
"my-agent-image",
command=["python", "-c", input_code],
read_only=True,
security_opt=["seccomp=seccomp-profile.json"],
remove=True,
mem_limit="512m",
network_disabled=True,
)
print(container.logs())
При таком подходе агент выполняется в временном контейнере без сети и с ограниченными системными вызовами.
7. Human‑in‑the‑loop и мониторинг
Механизм approval особенно важен для команд, которые:
- Модифицируют файлы (write, delete, chmod)
- Запускают новые процессы
- Устанавливают соединения по сети
Реализация в LangChain:
from langchain_community.tools import ShellTool
from langchain.agents import AgentExecutor
tool = ShellTool(approval_callback=human_approval)
def human_approval(command: str) -> bool:
print(f"Command to execute: {command}")
response = input("Approve? (y/n): ")
return response.lower() == 'y'
Мониторинг логов — фиксировать все команды, время выполнения, источник запроса. Это позволяет выявлять подозрительную активность и проводить аудит после инцидента.
Пет-проект для закрепления
Задача Разработать простого AI-агента (на базе LangChain или простого LLM), который может выполнять файловые операции (чтение, запись) в выделенной директории, но защищён от sandbox escape.
Инструменты
- Docker (контейнер с минимальным образом)
- Python + subprocess (только через allowlist команд)
- LangChain (опционально, для демонстрации agent loop)
Шаги:
- Создайте Dockerfile на основе
scratchилиdistrolessс одним бинарником (например, статически скомпилированным Python). - Реализуйте allowlist: разрешить только
lsиcatв/data. - Напишите простого агента, который принимает текстовый запрос («посмотри файл», «создай файл») и возвращает результат.
- Запустите агента с
read_only, отключите сеть, примените seccomp‑профиль. - Проверьте, что агент не может выполнить
rm -rf /илиcat /etc/passwd. - Добавьте human approval для любых операций записи.
Ожидаемый результат Агент корректно обрабатывает легитимные запросы и безопасно блокирует недопустимые команды, не допуская утечки данных.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 605 | Безопасность AI-агентов: общие принципы |
| 606 | Ограничение инструментов и функций агента |
| 608 | Изоляция выполнения кода (code interpreter safety) |
| 609 | Human‑in‑the‑loop в agentic pipeline |
| 610 | Мониторинг и логирование действий агента |
| 600 | Определение и архитектура Agentic RAG |
Навигация
- Предыдущий: 606
- Следующий: 608
- Индекс: 00. Индекс разборов