Скрытый долг безопасности vibe-coded приложений: уроки 155 запусков
Скорость против безопасности: ловушка AI-разработки
Бывало так: запускаешь утром чат с Lovable или Cursor, а к вечеру у тебя уже работающий сайт.SSL подключён автоматически, хостинг настроен — и вот ты показываешь друзьям работающий проект. Ощущение, будто попал в будущее.
Но правда в том, что быстрый запуск не значит безопасный запуск. И после того как я разобрался с исследованиями на эту тему, мне кажется, мы все немного недооцениваем риски этого «вечернего марафона».
Одно исследование просканировало 155 приложений, созданных с помощью AI-инструментов и запущенных в открытый доступ. 99 из них всё ещё работали и были доступны для анализа. Результаты одновременно успокаивают и настораживают.
Хорошая новость: секреты под защитой
Почти все разработчики уберегли свои ключи. Лишь 1% приложений случайно засветили настоящие секреты в браузере.
Никаких OpenAI API-ключей, которые кто-то мог бы использовать за ваш счёт. Никаких AWS credentials в клиентском коде. Никаких Stripe live-ключей, способных опустошить счёт.
Это говорит о том, что платформы вроде Bolt и Replit серьёзно прокачали свои настройки по умолчанию. При создании проекта тебя направляют в edge functions для работы с секретами, а не позволяют засветить их в браузерном бандле. Это реально качественный подход к security UX.
Но один процент — это всё ещё один процент слишком много. Один утекший ключ может стоить $50,000 на счете OpenAI, взломанного AWS-аккаунта или судебного спора с Stripe, который похоронит стартап на старте.
Проблема Supabase, о которой все молчат
Вот где начинается самое интересное.
37% живых AI-приложений содержат Supabase anonymous key в клиентском коде. И вот важный момент — это нормально. Supabase так спроектирован. Anon key публичный по задумке. Защита данных должна работать через RLS (Row Level Security).
Вот только RLS — это opt-in. Таблицы изначально полностью открыты. А когда ты кодишь в 11 вечера, пытаясь успеть к запуску, одну галочку пропустить проще простого.
Каждая таблица с отключённым RLS — или хуже, с политикой using (true) — это открытая дверь для любого, у кого есть публичный anon key. Атакующему не нужно ничего взламывать. Он просто сделает запрос к базе данных, потому что ты забыл про один переключатель.
Пассивное сканирование не увидит RLS-ошибки. Сканер смотрит только на фронтенд. Уязвимость живёт в базе данных. Проверять приходится руками, таблицу за таблицей.
То же касается Firebase (он встретился в 4% приложений). Security rules — не опциональная надстройка. Это вся модель безопасности.
Заголовки безопасности: невидимая рутина
Если ты никогда не слышал про HTTP security headers — ты в хорошей компании. 91% приложений не имеют Content-Security-Policy, а 88% можно встроить в iframe на любом сайте (привет, clickjacking).
Это не экзотические уязвимости. Это стандартный харденинг, который рекомендован годами. Просто AI-пайплайн не включает их по умолчанию.
Что показало сканирование:
- 91% — без Content-Security-Policy
- 88% — без X-Frame-Options / frame-ancestors
- 37% — без X-Content-Type-Options
- 38% — без Referrer-Policy
- 8% — без Strict-Transport-Security
- Только 5% — со всеми заголовками
Хорошая новость: хостинг-платформы автоматически ставят HSTS, так что этот пункт обычно в порядке. Но разрыв с CSP критичен. Когда AI-компонент рендерит пользовательский контент или подключает сторонние скрипты, CSP — последняя линия обороны. Без него XSS-атаки чувствуют себя вольготно.
Что забывают перед запуском
Одна находка удивила: 30% AI-приложений выходят в продакшн без Open Graph тегов.
Это значит, что когда кто-то кидает ссылку на твой продукт в X (Twitter), Discord или LinkedIn — там просто текст. Ни превью, ни картинки, ни описания. В 2024 году это выглядит несерьёзно и убивает кликабельность.
Другие типичные ошибки запуска:
- 11% — без meta description
- 77% — без sitemap.xml
- Средняя оценка безопасности: B- (84/100), и только 13% получили оценку A
Приложения не были катастрофами. Им просто не хватило финальной полировки. Та же скорость, которая донесла тебя до запуска, заставила забыть про <meta property="og:title">.
Чеклист из пяти минут перед запуском
После изучения этих данных я обновил свой личный чеклист. Вот что реально важно:
1. Найди секреты в бандле
Прогони поиск по собранному коду на sk-, sk_live_, service_role, ghp_. Всё найденное — срочно на ротацию и в edge function или переменную окружения. Один утекший ключ — это всё, что нужно атакующему.
2. Проверь каждую таблицу Supabase или Firebase
Открой дашборд. Каждая публичная таблица требует включённого RLS. Каждая политика должна быть конкретной — никаких using (true). Один открытый table может раскрыть всю базу пользователей.
3. Добавь security headers
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Если хочешь протестировать без блокировки — начни с Content-Security-Policy-Report-Only. Но задеплой это нужно.
4. Отключи source maps в продакшене
Файлы *.map — золото для отладки. Для атакующих тоже. Большинство платформ имеют переключатель. Выключи перед запуском.
5. Добавь Open Graph метаданные
Минимум: og:title, og:description, og:image. Твой launch-пост заслуживает красиво выглядеть в ленте.
6. Сгенерируй sitemap.xml
Твой будущий SEO-оптимизатор скажет спасибо. Многие платформы делают это автоматически — проверь, сделала ли твоя.
Главный вывод
Vibe coding — это не проблема. Проблема — разрыв между «работает на моей машине» и «готово к продакшену». Традиционные разработчики усвоили этот урок через годы болезненных деплоев. Vibe-разработчики усваивают быстрее — и это, в общем-то, неплохо.
Платформы становятся лучше. Настройки по умолчанию улучшаются. Но пока security hardening не станет таким же автоматическим, как SSL-сертификат, ответственность на нас.
Скорость vibe coding — это суперсила. Безопасность не обязана быть налогом за неё.