English translation is not available yet. Showing Russian content.

Что такое 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 — агент имеет вызовы для работы с файловой системой, сетью, процессами, что позволяет исследовать хост.

Пример типовой атаки:

  1. Пользователь отправляет запрос: «Выполни ls, а затем cat /etc/passwd».
  2. Агент (с помощью LLM) преобразует запрос в shell‑команду ls; cat /etc/passwd.
  3. Если 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)

Шаги:

  1. Создайте Dockerfile на основе scratch или distroless с одним бинарником (например, статически скомпилированным Python).
  2. Реализуйте allowlist: разрешить только ls и cat в /data.
  3. Напишите простого агента, который принимает текстовый запрос («посмотри файл», «создай файл») и возвращает результат.
  4. Запустите агента с read_only, отключите сеть, примените seccomp‑профиль.
  5. Проверьте, что агент не может выполнить rm -rf / или cat /etc/passwd.
  6. Добавьте human approval для любых операций записи.

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


Связь с другими вопросами

ВопросТема
605Безопасность AI-агентов: общие принципы
606Ограничение инструментов и функций агента
608Изоляция выполнения кода (code interpreter safety)
609Human‑in‑the‑loop в agentic pipeline
610Мониторинг и логирование действий агента
600Определение и архитектура Agentic RAG

Навигация