КИБЕРБЕЗОПАСНОСТЬ

Stack Overflow: AI пишет backend, но безопасность в него не входит

Express API с парой маршрутов может пройти тесты и уйти в прод с SSRF, открытым CORS и без лимита тела запроса — об этом пишет Stack Overflow Blog.

✍️ Редакция iTech News | 24.06.2026 | ⏱ 5 мин | Источник: Stack Overflow Blog
🔒

Код, который «поднимается» и отдает 200, еще не означает, что у вас есть безопасность backend. В колонке от 23 июня 2026 года автор Stack Overflow Blog разбирает типичный Node.js API, который AI-ассистент собирает за считаные минуты: маршруты работают, тесты зеленые, pull request открыт, а вместе с ним в прод спокойно уезжают SSRF, кривой CORS и отсутствие базовых лимитов.

Как пишет Stack Overflow Blog, проблема не в одной конкретной библиотеке и не в том, что разработчики внезапно разучились писать серверный код. Проблема в другом: генераторы кода и агентные инструменты отлично закрывают happy path, но почти не чувствуют, где заканчивается «работает» и начинается «опасно». Для русскоязычной команды это знакомый сценарий: дедлайн горит, AI быстро собрал сервис, тесты проходят, а аудит откладывается на потом. Потом обычно приходит инцидент, а не спокойный рефакторинг.

В качестве показательного примера автор берет простой API на Express. Набор почти учебниковый: express.json() без ограничения размера тела, cors() без настроек, маршрут /fetch-cover с прямым fetch(req.body.url), POST-маршрут /books без аутентификации и без валидации структуры запроса. Снаружи это выглядит безобидно: GET возвращает книгу, POST сохраняет данные, приложение слушает порт 3000. Внутри же копится классический набор проблем. Большой JSON можно буферизовать в память и положить процесс банальным DoS. Непроверенный URL в серверном fetch открывает дорогу к SSRF. В тексте прямо приведен адрес 169.254.169.254/latest/meta-data/iam/security-credentials/ — болезненно знакомая точка входа в облачных конфигурациях. А слепое доверие к req.body оставляет дверь приоткрытой для prototype pollution через __proto__.

Отдельно автор проходится по вещам, которые редко ловят автотесты, но которые хорошо видят сканеры и атакующие. Если у API нет rate limit, перебор и мусорные запросы становятся вопросом времени, а не мастерства. Если для неподдерживаемого метода сервер отвечает 404 вместо корректного 405 с заголовком Allow, это не просто косметика: так приложение врет о своей поверхности, а разработчики теряют контроль над контрактом. Если обработчик ошибок по умолчанию вываливает стек наружу, клиент получает лишнюю информацию о внутренностях сервиса. Тест при этом по-прежнему зеленый: отправили книгу, получили книгу, CI доволен. Уязвимости уходят в релиз с аккуратной зеленой галочкой.

Главный тезис материала звучит почти как претензия к целой индустрии AI-разработки: безопасное поведение должно быть дефолтом, а не дисциплиной по желанию. Автор цитирует мысль из разбора Supabase и Aikido: если поручить AI просто «сделать, чтобы работало», он может убрать те самые проверки, которые вас и защищают. Для человека это тоже не новость: ночью перед релизом разработчики совершают те же грехи. Разница в скорости и масштабе. Агент не устает, не нервничает и не чувствует внутреннего «подожди, а зачем тут вообще была эта проверка». Поэтому призыв «быть внимательнее» плохо масштабируется. Если код все чаще пишет машина, безопасность backend надо вшивать в рамки, а не надеяться на ручную добросовестность каждого автора pull request.

Дальше автор показывает ту же поверхность API, но уже на собственном TypeScript-фреймворке DaloyJS, который строится вокруг логики safe-by-default. В примере лимит тела запроса задан жестко: 64 * 1024 байт. Таймаут запроса — 5000 мс. Включены middleware для request ID, защитных заголовков, CORS с точным origin, а также rate limit на 120 запросов в минуту. POST-маршрут требует bearer-аутентификацию, а тело запроса описано через Zod-схему. Идея не в синтаксисе как таковом, а в смене базовой логики: чтобы сделать опасно, разработчик должен сознательно это включить, а не случайно унаследовать сомнительный шаблон из туториала или ответа ассистента.

Самое важное в этом примере — не «еще один фреймворк», а набор встроенных ограничителей. Тело запроса читается потоком, а Content-Length проверяется до буферизации. Это уже режет целый класс дешевых DoS-сценариев. Парсер JSON по умолчанию выбрасывает __proto__, constructor и prototype, закрывая известную дыру с загрязнением прототипов без дополнительного пакета «на всякий случай». Для необъявленного метода возвращается реальный 405, а ошибки оформляются в problem+json по RFC 9457; в production-режиме детали для 5xx автоматически скрываются. Наконец, схема запроса одновременно валидирует входные данные и становится источником OpenAPI-описания. Это практический момент: контракт, документация и проверка входа не расходятся по трем разным файлам, которые живут каждая своей жизнью.

Для команд, которые уже впустили AI в серверную разработку, посыл здесь довольно приземленный. Не важно, используете вы Express, Nest, Fastify или внутренний шаблон компании: если агент генерирует вам backend, в ревью нужно смотреть не только на бизнес-логику, но и на дефолты. Есть ли лимит тела? Что с SSRF? Как настроен CORS? Что происходит с неизвестными полями и методами? Утекают ли stack trace? Есть ли таймауты и rate limit? Именно здесь проходит граница между «ассистент ускорил команду» и «ассистент ускорил поставку будущего инцидента». AI хорошо пишет код, который запускается. Безопасность backend начинается в тот момент, когда платформа мешает вам принять зеленую галочку за признак готовности.

На этом фоне самый неприятный вопрос для рынка звучит просто: кто в компании отвечает за дефолты, если код теперь все чаще приходит не из головы разработчика, а из подсказки модели? Похоже, следующая конкуренция среди фреймворков и AI-инструментов будет идти не только за скорость генерации, но и за то, насколько трудно с их помощью случайно собрать уязвимый сервис.

Поделиться: Telegram X LinkedIn