Если вы создали приложение с помощью Claude или Cursor и собираетесь передать его платящему клиенту, остановитесь. Код, сгенерированный ИИ, содержит предсказуемые уязвимости безопасности — открытые API ключи, отсутствующая валидация входных данных, разрешения базы данных по умолчанию, которые позволяют любому пользователю видеть данные других. Это не граничные случаи. Они случаются почти в каждой первой версии кодовой базы, сгенерированной ИИ.
Это руководство — контрольный список проверки безопасности перед запуском. Следуйте ему пошагово перед тем, как к вашему приложению получит доступ любой реальный пользователь. Оно написано для самого распространённого стека (Next.js + Supabase + Vercel), но принципы применяются независимо от ваших инструментов.
Почему код, сгенерированный ИИ, имеет проблемы с безопасностью
Модели ИИ оптимизируют результат по принципу «работает ли это?», а не «это безопасно ли?». Когда вы говорите Claude «создай мне менеджер задач с учётными записями пользователей», он сгенерирует код, который создаёт пользователей, сохраняет задачи и отображает их. Что он, вероятно, не сделает автоматически: убедиться, что пользователь A не может видеть задачи пользователя B, убедиться, что поля ввода не могут принимать вредоносные скрипты, скрыть ваши API ключи от инструментов разработчика браузера или добавить ограничение частоты запросов, чтобы кто-то не смог забить ваши endpoints.
Это не недостатки ИИ — это пробелы в вашем запросе. ИИ создаёт то, что вы попросили. Вы, вероятно, не просили о безопасности, потому что сосредоточились на функциях. Теперь пришло время вернуться и добавить её.
Шаг 1: Проверьте переменные окружения
Это самая распространённая и самая опасная ошибка в приложениях, созданных вибом. Проверьте каждый файл в вашем проекте на наличие жёстко закодированных API ключей, URL-адресов баз данных или секретов.
Что искать: Поищите в вашей кодовой базе строки, которые начинаются с sk-, eyJ, sbp_, supabase, postgres:// или любые длинные строки случайных символов. Проверьте эти файлы в частности: любой файл в вашей директории /app или /pages, любой файл компонента, ваш next.config.js и любые файлы утилит.
Решение: Переместите каждый секрет в переменные окружения. В Next.js только переменные с префиксом NEXT_PUBLIC_ открыты для браузера. URL-адрес вашей базы данных, ключ service role и API секреты никогда не должны иметь этот префикс.
# .env.local (НИКОГДА не коммитьте этот файл)
SUPABASE_SERVICE_ROLE_KEY=your-secret-key
DATABASE_URL=postgres://...
# Эти переменные безопасны для браузера:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Проверка: Проверьте, включает ли ваш файл .gitignore .env.local. Если вы уже коммитили секреты в Git, они находятся в вашей истории даже после удаления — немедленно переизгенерируйте все открытые ключи.
Шаг 2: Включите Row-Level Security в Supabase
Это единственный самый критический шаг, если вы используете Supabase. По умолчанию таблицы Supabase не имеют ограничений доступа — любой, у кого есть ваш анон ключ, может читать и писать в каждую строку каждой таблицы. Это означает, что пользователь A может видеть данные пользователя B с помощью простого вызова API.
Решение: Включите Row-Level Security (RLS) на каждой таблице, затем создайте политики, которые ограничивают доступ.
Перейдите в панель управления Supabase → Table Editor → выберите каждую таблицу → нажмите «RLS Disabled», чтобы включить. Затем добавьте политики:
Для типичного приложения, где пользователи должны видеть только свои данные, создайте политику SELECT: auth.uid() = user_id. Создайте аналогичные политики для INSERT, UPDATE и DELETE.
Тестирование: Войдите как пользователь A, попытайтесь получить доступ к данным пользователя B через API. Если вы можете их видеть, ваши политики неправильные. Supabase имеет редактор SQL, где вы можете напрямую тестировать политики.
Типичная ошибка ИИ: Claude часто генерирует запросы Supabase, используя ключ service_role (который обходит RLS) вместо ключа anon с надлежащими политиками RLS. Проверьте, что код на стороне клиента использует только анон ключ. Ключ service role должен существовать только в коде на стороне сервера (API routes, server actions) и никогда не должен открываться браузеру.
Шаг 3: Добавьте аутентификацию правильно
Код аутентификации, сгенерированный ИИ, часто работает, но срезает углы. Проверьте эти конкретные проблемы:
Управление сеансом: Убедитесь, что сеансы истекают. Проверьте, что ваша настройка аутентификации включает разумный timeout сеанса (значения Supabase по умолчанию, как правило, в порядке, но проверьте). Убедитесь, что выход из системы действительно аннулирует сеанс, а не просто очищает локальный cookie.
Требования к пароли: Если у вас есть аутентификация по email/пароль, установите минимальную длину пароля (8+ символов). Supabase обрабатывает это в настройках вашего проекта → Authentication → Password Requirements.
Защищённые маршруты: Каждая страница, которая показывает пользовательские данные, требует middleware аутентификации. В Next.js App Router создайте middleware, которая проверяет наличие действительного сеанса и перенаправляет неаутентифицированных пользователей на страницу входа. Не полагайтесь только на проверки на стороне клиента — пользователь может их обойти, напрямую обратившись к вашему API.
Проверка email: Включите подтверждение email в настройках Supabase Auth. Это предотвращает создание учётных записей с поддельными адресами email и добавляет базовый уровень действительности учётной записи.
Вам это нравится? Мы публикуем один углубленный материал в неделю об инструментах ИИ, рабочих процессах и практических руководствах. Присоединитесь к читателям, которые получают это первыми →
Шаг 4: Валидируйте все входные данные
Формы, сгенерированные ИИ, обычно имеют базовую валидацию (обязательные поля, формат email), но редко защищают от вредоносного ввода.
Что добавить:
Валидация на стороне сервера на каждом API endpoint. Никогда не доверяйте только клиентской валидации — её можно обойти, отправляя запросы непосредственно на ваш API. Используйте библиотеку валидации, такую как Zod (для TypeScript), для определения схем для каждого фрагмента данных, которые принимает ваше приложение.
Санитизируйте HTML в любом пользовательском контенте, который отображается. Если в вашем приложении есть комментарии, описания или любое текстовое поле, которое отображается в браузере, используйте библиотеку, например DOMPurify, чтобы удалить опасные скрипты. Без этого кто-то может внедрить JavaScript, который украдёт сеансы других пользователей (cross-site scripting / XSS).
Ограничьте размер и типы файлов, если ваше приложение принимает загрузки файлов. Обработчики загрузки, сгенерированные ИИ, часто не имеют ограничений, что означает, что кто-то может загрузить файл размером 2 ГБ или исполняемый файл. Добавьте ограничения размера (5МБ разумны для большинства приложений) и ограничьте типы файлов только тем, что вам действительно нужно (изображения, PDF и т.д.).
Шаг 5: Защитите ваши API маршруты
Проверьте каждый API маршрут или server action в вашем приложении на наличие этих проблем:
Аутентификация на каждом endpoint. Каждый API маршрут, который возвращает или изменяет пользовательские данные, должен сначала проверить сеанс пользователя. ИИ часто генерирует API маршруты, которые принимают запросы от кого угодно.
Авторизация помимо аутентификации. Даже после подтверждения того, что пользователь вошёл в систему, убедитесь, что они имеют право доступа к конкретному ресурсу, к которому они обращаются. «Пользователь A вошёл в систему» не означает «Пользователь A может редактировать профиль пользователя B». Проверяйте принадлежность при каждом доступе к данным.
Ограничение частоты запросов. Без ограничения частоты запросов кто-то может отправить тысячи запросов в секунду на ваш API либо для соскребывания данных, либо для перегрузки вашего сервера. Добавьте базовое ограничение частоты запросов, используя библиотеку, например rate-limiter-flexible, или используйте встроенное ограничение частоты Vercel на Edge Functions.
HTTP методы. Убедитесь, что ваши API маршруты отвечают только на HTTP методы, которые они должны. Маршрут, который обрабатывает POST запросы, не должен также отвечать на DELETE запросы, если вы явно это не спроектировали.
Шаг 6: Проверьте конфигурацию развёртывания
Ваша платформа развёртывания имеет параметры безопасности, которые ИИ не настраивает для вас.
Параметры Vercel для проверки: Включите «Deployment Protection» (требует аутентификацию для просмотра развёртываний preview — предотвращает случайное совместное использование клиентами URL-адресов preview, которые раскрывают незавершённую работу). Установите ограничения на расходы, чтобы предотвратить неожиданные платежи, если ваше приложение получит скачок трафика. Настройте разрешённые домены в CORS заголовках.
Пользовательский домен и SSL: Если вы доставляете это клиенту, настройте его пользовательский домен с HTTPS. Vercel и Netlify автоматически обрабатывают SSL. Никогда не доставляйте клиентское приложение на поддомене .vercel.app — это выглядит непрофессионально и клиент не может легко его перенести.
Заголовки: Добавьте заголовки безопасности в ваш next.config.js или vercel.json: X-Content-Type-Options: nosniff, X-Frame-Options: DENY (предотвращает встраивание вашего сайта в iframe для атак на нажатие), Strict-Transport-Security (заставляет HTTPS). Это одноразовые дополнения, которые предотвращают целые классы атак.
Шаг 7: Запустите финальное сканирование безопасности
Перед передачей чего-либо клиенту запустите эти бесплатные проверки:
npm audit: Запустите npm audit в директории вашего проекта. Он помечает известные уязвимости в ваших зависимостях. Исправьте проблемы критической и высокой серьёзности. Запустите npm audit fix для автоматических исправлений, где они доступны.
Lighthouse: Откройте развёрнутый сайт в Chrome, откройте DevTools, запустите аудит Lighthouse. Проверьте оценку «Best Practices» — она ловит обычные проблемы безопасности, такие как отсутствие HTTPS, уязвимые библиотеки и небезопасные заголовки.
Ручное тестирование: Войдите как один пользователь, попытайтесь получить доступ к данным другого пользователя, изменяя URL-адреса или вызовы API. Попробуйте отправлять пустые формы, переразмеренные входные данные и специальные символы (например, закодированные XSS полезные нагрузки). Если что-либо из этого работает, у вас есть проблемы, которые нужно исправить.
Контрольный список перед запуском
Распечатайте это и проверьте каждый пункт перед запуском:
- Все секреты в переменных окружения (нет жёстко закодированных ключей)
.env.localв.gitignore(и нет секретов в истории Git)- Supabase RLS включён на каждой таблице
- Политики RLS протестированы (пользователь A не может видеть данные пользователя B)
- Код на стороне клиента использует только анон ключ (ключ service role только на стороне сервера)
- Аутентификация на каждом API маршруте
- Проверки авторизации (проверка принадлежности) при доступе к данным
- Валидация входных данных на каждой форме (серверная сторона, не только клиентская)
- Ограничения размера и типа файлов (если применимо)
- Ограничение частоты запросов на API endpoints
- Заголовки безопасности настроены
npm auditзапущен и критические проблемы исправлены- Пользовательский домен с SSL настроен
- Развёртывания preview защищены
- Тест доступа данных между пользователями вручную пройден
Главное
Защита приложения, созданного вибом, — это не вопрос становления экспертом в области безопасности. Речь идёт о прохождении контрольного списка, который ловит предсказуемые пробелы, которые оставляет ИИ. Шаги выше занимают 2–4 часа и предотвращают самые распространённые уязвимости. Для приложения, обращённого к клиенту, это не опционально — это разница между профессиональной работой и ответственностью.
Если вы создаёте своё первое приложение, созданное вибом, начните с нашего полного руководства по вибу кодингу. Если вы хотите улучшить подсказки, которые вы используете с Claude или Cursor, попробуйте наш бесплатный оптимизатор подсказок. И для разбора лучших инструментов кодирования см. Claude Code vs Codex.
Это то, что мы делаем каждую неделю. Один углубленный материал об инструментах ИИ, рабочих процессах и честных взглядах — без hype, без наполнения. Присоединитесь к нам →
Раскрытие: Некоторые ссылки в этой статье являются партнёрскими ссылками. Мы рекомендуем только инструменты, которые мы лично протестировали и регулярно используем. См. нашу полную политику раскрытия.