01В чём фокус
Ваше приложение можно взломать прямо сейчас. Не потому, что вы плохо вайбкодите, а потому, что агент по умолчанию делает так, чтобы работало, а не так, чтобы было безопасно.
Вас не будут ломать руками. По интернету круглосуточно ползают боты-сканеры, которые проверяют каждый новый сервер на открытые двери, и им совершенно всё равно, банк вы или проект, собранный за выходные. Новый сервер начинают сканировать за считанные секунды после публикации, а не через месяц, когда наберётся аудитория.
Хорошая новость в том, что почти все эти атаки сводятся к одному принципу, и, поняв его, вы закрываете сразу десяток разных дыр. Объясню по аналогии. Ваш сервер как официант. К нему приходят гости и что-то заказывают: гость говорит «бургер, пожалуйста», официант несёт бургер. Но представьте официанта, который выполняет вообще всё, что ему говорят, без раздумий. Гость говорит: «бургер, а ещё дай мне ключи от кассы», и официант отвечает: «окей, держите». Звучит глупо, но именно так работает огромная часть взломов. Хакер не выламывает дверь, он просит приложение сделать что-то лишнее, а приложение, если его не научили проверять, послушно это выполняет.
Первое и главное правило, если вы запомните только одну вещь из этого гайда: никогда не доверяйте данным, которые пришли от пользователя. Почти всё, что разобрано ниже, это разные вариации одной и той же проблемы, доверчивого официанта.
02Что нужно до старта
Любой стек. Принципы ниже не завязаны на конкретный язык или фреймворк. Где это важно, названы конкретные инструменты (ORM, CSP, SameSite), но идею агент переносит на ваш стек сам.
Не нужно быть программистом. Защита формулируется словами, которые вы отдаёте агенту как требование, а не как код, который пишете сами руками.
Честно про масштаб угрозы. Это гигиена, а не паранойя. Так же как мытьё рук не гарантирует, что вы не заболеете, но резко снижает шанс, разобранные ниже привычки не дают стопроцентной защиты, но закрывают подавляющее большинство реальных атак на небольшие проекты.
Проект, который уже принимает данные от пользователей. Форма входа, загрузка файлов, комментарии, оплата, что угодно. Чем раньше эти привычки появляются в проекте, тем дешевле они обходятся.
03Ядро
Атак много, а принцип один. Сервер обязан сам проверять то, что ему прислали, а не верить, что раз запрос выглядит правильно, значит он и есть правильный.
кто спрашивает сервер проверяет, что запрос пришёл именно от того,
кто прошёл авторизацию, а не просто выглядит как он
что спрашивает сервер проверяет, что запрашиваемые данные
принадлежат именно этому пользователю
что присылает сервер обрабатывает данные пользователя как данные,
а не как команду, которую нужно выполнить
откуда пришёл запрос сервер проверяет источник запроса, а не только
факт того, что в нём есть правильные куки
Четыре строки этой таблицы почти дословно превращаются в четыре известные атаки. Нарушение первой строки даёт слабую авторизацию и утечку сессии. Нарушение второй даёт IDOR, когда меняешь номер заказа в адресной строке и видишь чужой. Нарушение третьей даёт SQL-инъекцию и XSS: пользовательский текст выполняется как код вместо того, чтобы остаться текстом. Нарушение четвёртой даёт CSRF: чужой сайт присылает запрос от вашего имени, а сервер не проверяет, кто на самом деле его отправил.
Отдельная, новая категория появилась вместе с самим вайбкодингом: риски, которые в проект приносит не хакер, а собственный агент. Разберём все по порядку.

04Классические атаки и их лекарство
SQL-инъекция. Пользователь вписывает в обычное поле логина не имя, а специальную строку вроде admin' OR 1=1. Если запрос к базе собран склейкой строк, база выполняет это как часть команды, а не как текст, и хакер заходит без пароля вообще. Лекарство простое: держать команду и данные раздельно, и для этого не нужно писать код руками. ORM (Prisma для TypeScript, аналоги для других языков) делает это по умолчанию. Достаточно попросить агента использовать ORM вместо ручных SQL-запросов.
XSS. Хакер оставляет в комментарии или отзыве не текст, а спрятанный скрипт. Сам по себе, пока он лежит в базе, он безобиден. Проблема начинается, когда сайт показывает этот комментарий другому посетителю, а браузер выполняет скрипт вместо того, чтобы просто вывести его буквами. Защита двухслойная. React и большинство современных фреймворков по умолчанию выводят данные из базы как обычный текст, но у них есть команда для вставки настоящего HTML (dangerously set inner HTML в React), и вот она отключает эту защиту. Использовать её стоит только с дополнительной очисткой через библиотеку вроде DOMPurify. Второй слой, заголовок Content Security Policy: он говорит браузеру запускать только свои скрипты и игнорировать любую чужую вставку, даже если она каким-то образом просочилась на страницу.
CSRF. Атака хитрее, потому что жертва вообще ничего не делает. Пока у вас в одной вкладке открыта админка вашего сервиса, а в другой вы листаете мемы, левый сайт с мемами в фоне отправляет запрос в вашу админку. Браузер сам прикладывает к этому запросу ваши куки авторизации, и сервер выполняет команду, не заметив подмены. Защита требует двух настроек: флаг SameSite на куках (браузер сам не приложит их к запросу с чужого сайта) и CSRF-токен на важные действия (POST, DELETE), который чужой сайт угадать не может. В готовых фреймворках это обычно уже есть, достаточно попросить агента включить обе настройки.
IDOR и неправильные права доступа. Пользователь меняет номер заказа в адресной строке с 42 на 43 и видит данные чужого заказа. Причина всегда одна: сервер проверил, что пользователь авторизован, но не проверил, что именно эти данные принадлежат именно ему. Спрятать кнопку удаления в интерфейсе недостаточно: злоумышленник видит, какой запрос уходит на сервер по нажатию, и отправляет точно такой же напрямую. Проверка прав обязана жить на сервере, а не в интерфейсе, и должна отвечать сразу на два вопроса: залогинен ли пользователь и принадлежат ли эти данные именно ему.
05Пароли, сессии и ключи
Пароли никогда не хранятся как есть. В базу идёт не сам пароль, а его хэш, отпечаток, полученный по определённому алгоритму. При входе введённый пароль превращается в такой же хэш и сравнивается с сохранённым: совпало, значит верно.
Чтобы не просить пароль на каждой странице, сервер выдаёт сессию, браслет после входа на фестиваль. Храня эту сессию в куках, ставьте два флага: HttpOnly запрещает браузерным скриптам читать куки вообще (и тогда даже успешная XSS-атака не сможет украсть сессию), Secure разрешает передавать куки только по зашифрованному соединению https.
Дальше три простые, но обязательные настройки. Лимит на число попыток входа за отрезок времени останавливает перебор паролей: без него бот перебирает десятки тысяч комбинаций за час. Двухфакторная аутентификация добавляет второй подтверждающий код и заметно усиливает защиту аккаунта. И главное: не пишите систему авторизации с нуля сами. Готовые библиотеки вроде Better Auth для TypeScript удобнее, проще и надёжнее самодельной логики, и агент, скорее всего, сам предложит такое решение, если спросить его прямо.
Отдельная тема, ключи и пароли сервисов. Они никогда не идут в код, который попадает в браузер пользователя: там их видно через обычный просмотр исходного кода страницы, и даже взламывать ничего не нужно. Держите их в отдельном файле переменных окружения (.env) и добавляйте этот файл в .gitignore, чтобы он не попал в Git. Публикуется только .env.example со списком нужных переменных, без самих значений. Боты регулярно сканируют весь GitHub именно в поисках случайно закоммиченных ключей и находят их за считанные минуты после публикации. Если ключ всё же утёк, недостаточно его удалить из кода: он остаётся в истории изменений Git навсегда, поэтому ключ нужно ещё и деактивировать в панели того сервиса, для которого он выпущен, и выпустить новый.
06Хранилища и инфраструктура
Файлы пользователей (аватарки, документы) обычно хранят не на самом сервере, а в S3-хранилище, и у него есть настройка публичности, за которой легко не уследить. Открытое хранилище означает, что любой человек, зная ссылку, получает файл, а если в нём случайно можно получить список всех файлов, это уже утечка всех документов разом. Правильная схема держит хранилище закрытым, а доступ выдаёт через временные подписанные ссылки либо через сервер-посредник, который сам ходит в хранилище и отдаёт файл пользователю. Для действительно публичных файлов, вроде аватарок или картинок товаров, заводится отдельный открытый бакет, а не общий с приватными данными.
База данных по возможности изолируется от публичной сети: либо объединяется с сервером приложения в приватную сеть провайдера, либо закрывается файрволом с доступом только по конкретным IP-адресам. Доступ к самому серверу по SSH настраивается только по ключу, не по паролю, и не от пользователя root, а от отдельного администратора: пароль можно подобрать перебором, ключ практически нет.
07Риски, которые приносит собственный агент
Это угроза, которой пять лет назад просто не существовало: дыру приносит не хакер, а тот самый инструмент, которым вы пишете код.
Выдуманные пакеты. Агент может прописать название библиотеки, которой не существует, галлюцинацию. Современные модели делают это заметно реже, чем раньше, но риск не нулевой, и опасность в том, что такие выдумки повторяемы: модель может придумать одно и то же несуществующее имя снова и снова в похожих ситуациях. Злоумышленники это заметили и специально регистрируют пакеты с такими именами, подкладывая внутрь вредоносный код. Технически всё установится без единой ошибки, поэтому стоит время от времени проверять, что подключённые агентом библиотеки реальны и официальны, а не просто что код скомпилировался.
Агент не приоритизирует безопасность сам по себе. В первую очередь он делает так, чтобы работало, а безопасность у него на втором плане. Единственный способ это изменить, прямо прописать требования безопасности в файле правил проекта или в отдельном скилле, а не надеяться, что агент сам обо всём подумает.
Промт-инъекция. Спрятанная команда для агента в файле, посте или комментарии, который агент читает как обычный текст. Классический пример: скачанный без проверки скилл содержит инструкцию отправлять ключи и пароли на сторонний адрес при определённых действиях, и агент выполняет её так же послушно, как любую другую инструкцию, потому что для него это неотличимо от вашего собственного промпта. Другой вариант: белый текст на белом фоне в комментарии на форуме, невидимый человеку, но полностью читаемый агентом. Три защитные меры: относитесь к агенту как к недоверенному новому сотруднику и не давайте ему больше доступа, чем нужно для конкретной задачи; будьте особенно осторожны, когда агент взаимодействует с внешними источниками (веб-поиск, чужие репозитории, скачанные скиллы), а не только с вашими локальными файлами; включайте режим подтверждения важных действий именно в моменты работы с внешним контентом.
Нейронка, встроенная в ваше приложение. Если пользователи вашего сервиса сами общаются со встроенным ассистентом, у него не должно быть прямого доступа к базе данных целиком: без отдельной прослойки с проверкой прав любопытный пользователь может уговорить модель выдать чужие данные, представившись администратором или придумав срочную причину.
08Бесплатные настройки, которые почти ничего не стоят
Пять мелочей, которые вместе закрывают внушительный кусок поверхности атаки, и каждая занимает один промпт агенту.
HTTPS. Без зашифрованного соединения пароли летят по сети открытым текстом. SSL-сертификат на многих платформах (Vercel, Railway и аналогичных) настраивается автоматически, покупать его отдельно обычно не нужно.
Заголовок X-Frame-Options со значением deny. Защита от кликджекинга: злоумышленник встраивает ваш сайт невидимым слоем поверх своей страницы, и пользователь, думая, что нажимает безобидную кнопку, на самом деле кликает по интерфейсу вашего сервиса.
Регулярное обновление зависимостей. Библиотеки со временем устаревают, и в старых версиях находят уязвимости, для которых давно вышло исправление. Периодически просите агента проверить и обновить пакеты проекта.
Лимит запросов (rate limit). Без него бот может перебирать пароли всю ночь либо просто положить сервер потоком запросов. Отдельно стоит ограничить траты на платные API нейронок: без лимита баг с циклом в коде способен превратить ожидаемые пять долларов в день в пять тысяч.
Не показывать пользователю текст системной ошибки. Внутренняя ошибка сервера может содержать детали кода или структуры базы. Пользователь должен видеть нейтральное «что-то сломалось, попробуйте позже», а саму ошибку логировать себе, например в отдельный Telegram-канал.
09Свой результат за вечер
Четыре шага, от самого дешёвого к самому объёмному.
Шаг первый. Бесплатные настройки. HTTPS, X-Frame-Options deny, свежие зависимости, лимит запросов, нейтральные сообщения об ошибках. Каждая настройка это один короткий промпт, а вместе они закрывают неожиданно много.
Шаг второй. Ключи и хранилища. Проверьте, что все ключи вынесены в .env и файл добавлен в .gitignore. Проверьте настройки приватности S3-хранилища и доступ к базе данных по IP или приватной сети.
Шаг третий. Классические атаки. Спросите агента, используется ли ORM, настроены ли SameSite и CSRF-токены, проверяет ли сервер права доступа к конкретным данным, а не только факт авторизации.
Шаг четвёртый. Правила для агента. Пропишите требования безопасности в файл правил проекта, чтобы они применялись автоматически к каждому новому куску кода, а не проверялись вручную и не раз за весь проект целиком.

10Что ты увидишь
Было. Агент делает так, чтобы функция работала, и на этом останавливается. Ключи иногда всплывают прямо в коде для скорости, кнопки скрываются в интерфейсе вместо проверки на сервере, и всё это незаметно, пока кто-то не наткнётся специально или автоматическим сканером.
Стало. Требования безопасности прописаны один раз и применяются к каждой новой фиче автоматически. Боты, которые сканируют ваш сервер в первую же минуту после публикации, не находят открытых дверей.
Обратная сторона честно: разобранные привычки требуют держать их в голове или в файле правил постоянно, а не один раз перед запуском. Проект растёт, добавляются новые формы и эндпоинты, и каждый из них нужно провести через тот же список.
11Чтобы не споткнуться
Спрятать кнопку в интерфейсе и решить, что этого достаточно. Обычный пользователь на неё не нажмёт, но злоумышленник отправляет запрос напрямую, минуя интерфейс целиком. Проверка обязана жить на сервере.
Скачать скилл или правило для агента, не прочитав его. Инструкция внутри воспринимается агентом как ваша собственная просьба, без разницы, откуда она взялась.
Решить, что раз репозиторий приватный, ключи в коде безопасны. К приватному репозиторию со временем получают доступ другие разработчики, а сам агент читает файлы проекта при каждой правке. Ключи всё равно выносятся в переменные окружения.
12А если…
А если у меня совсем маленький проект без пользователей?
Боты не выбирают жертву по размеру, они сканируют всё подряд. Настройка базовых пунктов занимает один вечер и один раз, откладывать дороже, чем сделать сразу.
А если агент сам предложит использовать ORM и готовую авторизацию без напоминаний?
Отлично, современные модели действительно всё чаще делают это сами. Но проверить стоит явно, а не полагаться на удачу: спросите прямым текстом, используется ли ORM и откуда взята логика авторизации.
А если нужно всё же использовать dangerously set inner HTML?
Только вместе с очисткой через библиотеку вроде DOMPurify, которая вырезает исполняемые скрипты и оставляет чистый HTML.
А если я не пишу сам код и не понимаю половину терминов?
Ровно поэтому все формулировки в этом гайде рассчитаны на то, чтобы их скопировать в промпт агенту как требование, а не разбираться в реализации самостоятельно.
А если хочется автоматической проверки, а не помнить весь список руками?
Соберите из практических блоков этого гайда отдельный файл правил или попросите агента проанализировать проект и держать в контексте этот список при каждой новой фиче.
13Зачем на самом деле
Безопасность это не список страшных терминов для «настоящих» разработчиков. Это понимание конкретных способов атаки, и, поняв способ один раз, закрываешь дыру навсегда, а не до следующего похожего взлома.
Один и тот же принцип, не доверять данным от пользователя, лечит и SQL-инъекцию, и XSS, и CSRF, и IDOR. Это не десять разных наук, а один навык, применённый в разных местах. И ровно поэтому его дешевле встроить в правила агента один раз, чем держать в голове и проверять вручную на каждой новой фиче.
Отдельная честная мысль напоследок: с появлением ИИ-агентов поверхность атаки не сократилась, а выросла. Агент, который просто делает так, чтобы работало, и не приоритизирует безопасность сам, это не теоретический риск, а реальность по умолчанию. Разница между взломанным и защищённым проектом всё чаще не в таланте разработчика, а в том, прописаны ли эти требования явно.
14А дальше
Агент чинит одно и тихо ломает другое. Вот защита про соседнюю привычку того же уровня: автотесты, которые сами проверяют, что агент не сломал старую функцию, добавляя новую. Тесты и безопасность решают разные задачи, но обе держатся на одном принципе, не верить агенту на слово, а требовать доказательство.
15Источники
OWASP Top 10: https://owasp.org/www-project-top-ten/ Официальный и самый авторитетный список категорий веб-уязвимостей, основа для большинства разобранных здесь атак.
MDN, Content Security Policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP Официальная документация по заголовку CSP и защите от XSS.
MDN, SameSite cookies: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite Как флаг SameSite защищает от CSRF-атак.
Better Auth: https://www.better-auth.com/ Готовая библиотека авторизации для TypeScript, упомянутая как альтернатива самописной системе входа.
DOMPurify: https://github.com/cure53/DOMPurify Библиотека очистки HTML от исполняемых скриптов перед вставкой непроверенного содержимого на страницу.
Prisma: https://www.prisma.io/ ORM для TypeScript, снимающая необходимость писать SQL-запросы руками и закрывающая SQL-инъекции по умолчанию.
Исходное видео: «Вайбкодишь? Тебя взломают. Вот как защититься!», youtube.com/watch?v=FnLrNRI_Fsg Первоисточник структуры разбора атак и мысли о доверчивом официанте, изложенных в этом гайде своими словами.
Собрал бота. А как собрать конвейер?
Один бот закрывает одну задачу. Дальше начинается связка: n8n, Make, агенты в Claude Code и то, что крутится без тебя. Это уже не «ещё один инструмент», а система.
Что за клуб →