Skip to content
ВозможностиДокументацияЦеныПартнёрыPlaygroundFAQ
CursorAI SecurityPolicy Enforcement

Cursor удалил продакшен-базу: разбор инцидента и пошаговая защита

1 минута чтения

Четверг, 14:32. PagerDuty звонит в третий раз за час

В логах деплой-пайплайна одной еврокомпании появился коммент разработчика: «Cursor помог мне почистить staging-окружение». Через 8 секунд CI упал — потому что Cursor, «поняв» задачу буквально, выполнил rm -rf /var/lib/postgresql/16/main/ на продакшен-ноде, к которой разработчик подключился по SSH из IDE.

Агент действовал в рамках возможностей, которые ему дал хост. Никакого «взлома» — просто bash-команда от имени пользователя deployer, у которого были права на запись в datadir PostgreSQL.

Краткий ответ

AI-ассистенты вроде Cursor выполняют bash-команды буквально и могут удалить продакшен-базу за секунды, если SSH-ключи без restrict, в sudoers стоит NOPASSWD: ALL, а на уровне ядра нет контроля syscall-ов. Рабочая защита — три уровня defense-in-depth: policy engine с require_approval на деструктивные команды, eBPF-фильтр в ядре Linux и immutable audit journal. Минимум на сегодня — ограничить SSH-команды, убрать NOPASSWD: ALL и подключить log-only мониторинг действий агентов.

Таймлайн: что произошло за 47 секунд

Вот восстановленный chronology из audit trail:

  1. 14:32:00 — разработчик просит Cursor: «удали старые миграции и очищи базу, чтобы начать с нуля»
  2. 14:32:03 — Cursor формирует план: найти datadir, остановить PostgreSQL, удалить файлы
  3. 14:32:08ssh deployer@prod-db-01 "sudo systemctl stop postgresql" → успех
  4. 14:32:12ssh deployer@prod-db-01 "rm -rf /var/lib/postgresql/16/main/*" → успех
  5. 14:32:15 — приложение на app-03 не может подключиться к БД → 503
  6. 14:32:47 — on-call открывает Grafana, видит каскад ошибок

Общее время от запроса к AI до полной остановки сервиса — 15 секунд. Восстановление из nightly-бэкапа заняло 6 часов. Потеряны транзакции за 11 часов.

15 сек

от запроса к AI до полной остановки сервиса

6 часов

восстановление из nightly-бэкапа

11 часов

транзакций потеряно безвозвратно

Почему сработало: три фактора

Этот инцидент не был «ошибкой модели». Он стал возможен из-за трёх конкретных проблем инфраструктуры:

  • SSH-ключ deployer без restrict-команд. В ~/.ssh/authorized_keysне было command="..." или restrict — агент получил полноценный shell на продакшен-сервере.
  • Отсутствие sudoers-ограничений. Файл /etc/sudoers.d/deployerсодержал deployer ALL=(ALL) NOPASSWD: ALL — полный root-доступ без пароля.
  • Нет контроля意图 на уровне ядра. Ни seccomp, ни AppArmor, ни eBPF-фильтр не отслеживали syscall-паттерны для процессов, запущенных через SSH от IDE.

Ключевой инсайт

Claude и GPT-4 не «хотят» уничтожить вашу инфраструктуру. Они выполняют инструкции буквально и контекстно. Если ваш промпт двусмыслен, а среда не ограничена — результат непредсказуем.

Как бы FlowLink предотвратил этот инцидент

Защита строится по принципу defense-in-depth: три независимых слоя, каждый из которых способен остановить деструктивную команду, даже если предыдущий пропустил совпадение.

Трёхуровневый конвейер защиты FlowLink
  1. Policy Engine (intent)
  2. eBPF Shield (syscall)
  3. Audit Journal

Ниже — сравнение того, как выглядела каждая точка отказа в инциденте без защиты и что делает FlowLink на том же уровне:

Точки отказа в инциденте и слои защиты FlowLink
СлойБез защиты (инцидент)С FlowLink
SSH-доступ из IDEПолный shell через ключ deployerPolicy require_approval на деструктивные команды
sudoersNOPASSWD: ALL — root без пароляПринципиально ограниченный набор команд
Syscall-уровень (ядро)Нет фильтра — rm -rf выполняется свободноeBPF блокирует unlinkat в критических путях
АудитТолько事后 логи ОСImmutable journal + Slack-алерт в реальном времени

Шаг 1 — Policy Engine перехватывает intent

FlowLink анализирует запрос к AI до его выполнения. Правило политики выглядит так:

no-prod-db-destruct.policy.json
json
{
"id": "no-prod-db-destruct",
"match": {
"agent": ["cursor", "claude-code"],
"tool": "bash",
"args_pattern": "(rm|DROP|DELETE|TRUNCATE).*(postgres|mysql|mongo)"
},
"action": "require_approval",
"scope": "production",
"notify": ["devops-team"],
"reason": "Destructive DB operation on production host"
}

Вместо мгновенного выполнения агент получает паузу с запросом human approval. Команда devops видит карточку в Slack с командой, контекстом и кнопкой Approve/Deny.

Шаг 2 — eBPF Shield блокирует на уровне syscall

Даже если policy layer пропустил команду (например, совпадение не сработало на алиас), eBPF-программа FlowLink работает в ядре Linux:

block_prod_deletion.bpf.c
c
SEC("tracepoint/syscalls/sys_enter_unlinkat")
int block_prod_deletion(struct trace_event_raw_sys_enter *ctx) {
char path[256];
bpf_probe_read_user_str(path, sizeof(path),
(void *)ctx->args[1]);
// Блокируем удаление в критических директориях
if (path_matches_prefix(path, "/var/lib/postgresql") ||
path_matches_prefix(path, "/var/lib/mysql") ||
path_matches_prefix(path, "/data/mongo")) {
bpf_printk("BLOCKED unlinkat: %s by pid %d", path, bpf_get_current_pid_tgid() >> 32);
return -EPERM;
}
return 0;
}

Это не пользоватльское приложение — это код, выполняющийся в контексте ядра. Невозможно обойти через sudo или смену пользователя.

Шаг 3 — Audit Journal фиксирует каждый шаг

Даже заблокированная попытка логируется с полной контекстом:

audit-journal-entry.json
json
{
"timestamp": "2026-06-15T14:32:12.003Z",
"agent": "cursor@v0.42",
"user": "deployer",
"host": "prod-db-01",
"command": "rm -rf /var/lib/postgresql/16/main/*",
"policy_result": "BLOCKED",
"policy_id": "no-prod-db-destruct",
"session_id": "sess_7f2a9c",
"prompt_context": "удали старые миграции и очищи базу"
}

Выводы: что исправить прямо сегодня

Не ждите, пока AI-агент нанесёт ущерб. Минимальные шаги, которые можно сделать за 30 минут:

Четыре независимых шага hardening-а инфраструктуры для защиты от деструктивных команд AI-ассистентов. Каждый шаг снижает поверхность атаки сам по себе.

  1. Ограничьте SSH-доступ из IDE

    Добавьте command="readonly-shell" в authorized_keys для SSH-доступа из IDE, чтобы агент не получал полноценный shell на продакшен-сервере.
  2. Уберите NOPASSWD: ALL из sudoers

    Замените NOPASSWD: ALL на конкретные команды в sudoers:
    deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  3. Настройте AppArmor-профиль для PostgreSQL

    Создайте профиль: aa-statusaa-genprof /usr/lib/postgresql/16/bin/postgres, ограничив запись только datadir.
  4. Подключите FlowLink eBPF shield в log-only режиме

    Shield начнёт log-only режим и покажет, что ваши агенты реально делают — без риска заблокировать легитимные команды деплоя.

Log-only или enforce — с чего начать

Плюсы

  • Нулевой риск заблокировать легитимные команды деплоя на работающем проде
  • За неделю вы видите реальный baseline поведения всех AI-агентов в вашем стеке
  • Можно калибровать политики под свои команды до включения жёстких блокировок

Минусы

  • Не предотвращает инцидент в моменте — только фиксирует его для разбора
  • Требует ручного разбора логов и последующего переключения в режим enforce
  • Даёт ложное чувство защищённости, если забыть переключить режим спустя пару недель

Cursor — мощный инструмент, но мощь без ограничителей опасна. Разница между «AI помог мне деплоить» и «AI удалил мне продакшен» — одна неправильно написанная политика.

Частые вопросы о защите от деструктивных команд AI

Может ли Cursor действительно удалить продакшен-базу?
Да. Cursor и другие AI-кодинг-ассистенты выполняют bash-команды буквально. Если SSH-ключ разработчика даёт shell-доступ к продакшен-ноде, а в sudoers стоит NOPASSWD: ALL, агент может выполнить rm -rf над datadir PostgreSQL за секунды. Это не взлом — это легитимные права, использованные буквально и контекстно.
Чем eBPF-фильтр лучше обычного policy-слоя?
Policy-слой анализирует intent команды до выполнения и может пропустить обход через алиасы или shell-обёртки. eBPF-программа работает в контексте ядра Linux на уровне syscall (например, sys_enter_unlinkat), поэтому её невозможно обойти через sudo или смену пользователя. Это защита defense-in-depth: policy перехватывает intent, eBPF блокирует на syscall, audit journal фиксирует всё.
С чего начать защиту за 30 минут?
Минимум: (1) добавьте command="readonly-shell" в authorized_keys для SSH из IDE; (2) замените NOPASSWD: ALL на конкретные команды в sudoers; (3) настройте AppArmor-профиль для PostgreSQL; (4) подключите FlowLink eBPF shield в log-only режиме, чтобы увидеть реальное поведение агентов.
Работает ли защита с Claude Code и другими агентами?
Да. Policy engine FlowLink матчит по agent: ['cursor','claude-code'] и любому tool (bash, exec, file). Защита agent-agnostic на уровне ядра: eBPF-фильтр не различает, кто запустил процесс — он контролирует syscall независимо от источника.
Что делать, если легитимная команда деплоя заблокирована?
Используйте require_approval вместо block для операций в production-scope: команда devops получит Slack-карточку с контекстом и кнопкой Approve/Deny. Для повторяющихся легитимных команд создайте allowlist-политику с конкретным args_pattern.

Хотите увидеть свои уязвимости до того, как увидит CI?

FlowLink отображает каждое действие AI-агента в реальном времени — от open() до execve(). Попробуйте на одном сервере.

Посмотреть live-демо