Если вы написали приложение на Claude или Cursor в режиме "вайб-кодирования" и собираетесь передать его платящему клиенту, остановитесь. AI-генерированный код содержит предсказуемые дыры безопасности — открытые API-ключи, отсутствие валидации входных данных, стандартные разрешения базы данных, которые позволяют любому пользователю видеть данные всех остальных. Это не граничные случаи. Они встречаются почти в каждой первой версии AI-генерированного кода.
Это руководство — чек-лист безопасности перед запуском. Следуйте ему пошагово, прежде чем на приложение будут доступ реальные пользователи. Оно написано для наиболее распространённого стека "вайб-кодирования" (Next.js + Supabase + Vercel), но принципы применимы к любым инструментам.
Почему AI-генерированный код имеет проблемы с безопасностью
AI-модели оптимизируют "это работает?" а не "это безопасно?" Когда вы скажете Claude "создай мне приложение для управления задачами с учётными записями", он сгенерирует код, который создаёт пользователей, сохраняет задачи и отображает их. Что он вероятно не сделает автоматически: убедиться, что Пользователь A не может видеть задачи Пользователя B, проверить, что поля ввода не могут принять вредоносные скрипты, скрыть ваши API-ключи от инструментов разработчика браузера или добавить ограничение частоты, чтобы предотвратить массовые запросы к ваши конечным точкам.
Это не недостатки AI — это пробелы в промпте. AI создаёт то, что вы просили. Вероятно, вы не просили о безопасности, потому что сосредоточились на функциях. Теперь пришло время вернуться и добавить её.
Шаг 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=ваш-секретный-ключ
DATABASE_URL=postgres://...
# Это нормально открывать браузеру:
NEXT_PUBLIC_SUPABASE_URL=https://ваш-проект.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=ваш-anon-ключ
Проверка: Убедитесь, что в файле .gitignore указан .env.local. Если вы уже закоммитили секреты в Git, они находятся в вашей истории даже после удаления — немедленно переполучите (переформируйте) каждый открытый ключ.
Шаг 2: Включите Row-Level Security в Supabase
Это наиболее критически важный шаг, если вы используете Supabase. По умолчанию таблицы Supabase не имеют ограничений доступа — каждый с вашим anon-ключом может читать и писать каждую строку в каждой таблице. Это означает, что Пользователь 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, где вы можете напрямую тестировать политики.
Распространённая ошибка AI: Claude часто генерирует запросы Supabase, используя ключ service_role (который обходит RLS) вместо ключа anon с правильными политиками RLS. Убедитесь, что ваш код на стороне клиента использует только anon-ключ. Ключ service role должен существовать только в серверном коде (API-маршруты, серверные экшны) и никогда не быть открыт браузеру.
Шаг 3: Добавьте аутентификацию правильно
AI-генерированный код аутентификации часто работает, но срезает углы. Проверьте эти конкретные проблемы:
Управление сессией: Убедитесь, что сессии истекают. Проверьте, что ваша аутентификация включает разумный timeout сессии (стандартные значения Supabase обычно нормальны, но проверьте). Убедитесь, что выход действительно инвалидирует сессию, а не просто очищает локальный cookie.
Требования к паролю: Если у вас есть аутентификация по email/паролю, требуйте минимальную длину пароля (8+ символов). Supabase обрабатывает это в настройках проекта → Authentication → Password Requirements.
Защищённые маршруты: Каждая страница, которая показывает данные конкретного пользователя, нуждается в middleware аутентификации. В Next.js App Router создайте middleware, который проверяет наличие корректной сессии и перенаправляет неаутентифицированных пользователей на страницу входа. Не полагайтесь только на проверки со стороны клиента — пользователь может их обойти, обратившись прямо к вашему API.
Проверка email: Включите подтверждение email в настройках Supabase Auth. Это предотвращает создание учётных записей с поддельными email-адресами и добавляет базовый уровень проверки корректности аккаунта.
Получаете пользу от этого? Мы публикуем одну углублённую статью в неделю об инструментах AI, рабочих процессах и практических руководствах. Присоединитесь к читателям, которые узнают об этом первыми →
Шаг 4: Проверяйте все входные данные
AI-генерированные формы обычно имеют базовую валидацию (обязательные поля, формат email), но редко защищают от вредоносного ввода.
Что добавить:
Валидация на стороне сервера на каждой конечной точке API. Никогда не полагайтесь только на валидацию со стороны клиента — её можно обойти, отправляя запросы прямо к вашему API. Используйте библиотеку валидации как Zod (для TypeScript), чтобы определить схемы для каждого фрагмента данных, которые ваше приложение принимает.
Санитизируйте HTML в любом пользовательском контенте, который отображается. Если ваше приложение содержит комментарии, описания или любое текстовое поле, которое отображается в браузере, используйте библиотеку как DOMPurify, чтобы удалить опасные скрипты. Без этого кто-то может внедрить JavaScript, который украдёт сессии других пользователей (кросс-сайтовый скриптинг / XSS).
Ограничьте размер и тип файлов, если ваше приложение принимает загрузки файлов. AI-генерированные обработчики загрузок часто не имеют ограничений, что означает, что кто-то может загрузить файл размером 2GB или исполняемый файл. Добавьте ограничения размера (5MB разумно для большинства приложений) и ограничьте типы файлов тем, что вам действительно нужно (изображения, PDF и т.д.).
Шаг 5: Защитите ваши API-маршруты
Проверьте каждый API-маршрут или серверный экшн в вашем приложении на эти проблемы:
Аутентификация на каждой конечной точке. Каждый API-маршрут, который возвращает или изменяет данные пользователя, должен сначала проверить сессию пользователя. AI часто генерирует API-маршруты, которые принимают запросы от кого угодно.
Авторизация помимо аутентификации. Даже после подтверждения, что пользователь вошёл, убедитесь, что он имеет право доступа к конкретному ресурсу, который он запрашивает. "Пользователь A вошёл" не означает "Пользователь A может редактировать профиль Пользователя B." Проверяйте права собственности при каждом доступе к данным.
Ограничение частоты. Без ограничения частоты, кто-то может отправить тысячи запросов в секунду к вашему API, либо для скрепинга данных, либо для перегрузки сервера. Добавьте базовое ограничение частоты, используя библиотеку как rate-limiter-flexible или используйте встроенное ограничение частоты Vercel на Edge Functions.
HTTP-методы. Убедитесь, что ваши API-маршруты отвечают только на те HTTP-методы, на которые они должны. Маршрут, обрабатывающий POST-запросы, не должен также отвечать на DELETE-запросы, если вы не спроектировали его специально.
Шаг 6: Проверьте конфигурацию развёртывания
Платформа развёртывания имеет параметры безопасности, которые AI не конфигурирует для вас.
Параметры Vercel для проверки: Включите "Deployment Protection" (требует аутентификацию для просмотра preview-развёртываний — предотвращает случайное открытие preview-URLs клиентами). Установите лимиты расходов, чтобы предотвратить неожиданные платежи при скачках трафика. Настройте разрешённые домены в CORS-заголовках.
Пользовательский домен и SSL: Если вы развёртываете это для клиента, установите их пользовательский домен с HTTPS. Vercel и Netlify обрабатывают SSL автоматически. Никогда не развёртывайте клиентское приложение на поддомене .vercel.app — это выглядит непрофессионально и клиент не сможет легко его перенести.
Заголовки: Добавьте заголовки безопасности в ваш next.config.js или vercel.json: X-Content-Type-Options: nosniff, X-Frame-Options: DENY (предотвращает встраивание вашего сайта в iframe для clickjacking), Strict-Transport-Security (принудительно включает HTTPS). Это одноразовые добавления, которые предотвращают целые классы атак.
Шаг 7: Запустите финальную проверку безопасности
Перед передачей чего-либо клиенту запустите эти бесплатные проверки:
npm audit: Запустите npm audit в директории вашего проекта. Это отмечает известные уязвимости в ваших зависимостях. Исправьте critical и high-severity проблемы. Запустите npm audit fix для автоматического исправления, где это возможно.
Lighthouse: Откройте развёрнутый сайт в Chrome, откройте DevTools, запустите аудит Lighthouse. Проверьте оценку "Best Practices" — она выявляет распространённые проблемы безопасности как отсутствие HTTPS, уязвимые библиотеки и небезопасные заголовки.
Ручное тестирование: Войдите как один пользователь, попробуйте получить доступ к данным другого пользователя, изменяя URLs или вызовы API. Попробуйте отправлять пустые формы, переразмеренные входы и специальные символы (как закодированные XSS-полезные нагрузки). Если что-либо из этого работает, у вас есть проблемы для исправления.
Чек-лист перед запуском
Распечатайте это и проверьте каждый пункт перед запуском:
- Все секреты в переменных окружения (нет жёстко закодированных ключей)
.env.localв.gitignore(и нет секретов в истории Git)- Supabase RLS включена на каждой таблице
- RLS-политики проверены (Пользователь A не может видеть данные Пользователя B)
- Код на стороне клиента использует только anon-ключ (service role-ключ только на серверной стороне)
- Аутентификация на каждом API-маршруте
- Проверки авторизации (проверка прав собственности) при доступе к данным
- Валидация входных данных на каждой форме (серверная, не только клиентская)
- Ограничения размера и типа файлов загрузок, если применимо
- Ограничение частоты на конечных точках API
- Заголовки безопасности сконфигурированы
npm auditзапущен и critical-проблемы исправлены- Пользовательский домен с SSL сконфигурирован
- Preview-развёртывания защищены
- Ручное тестирование кросс-доступа к данным пользователя пройдено
Главное
Защита приложения, написанного в режиме "вайб-кодирования", не о том, чтобы стать экспертом по безопасности. Это о прохождении чек-листа, который выявляет предсказуемые пробелы, которые оставляет AI. Шаги выше занимают 2–4 часа и предотвращают наиболее распространённые уязвимости. Для приложения, предназначенного для клиента, это не опционально — это разница между профессиональной работой и ответственностью.
Если вы строите своё первое приложение, написанное в режиме "вайб-кодирования", начните с нашего полного руководства по вайб-кодированию. Если вы хотите улучшить промпты, которые вы используете с Claude или Cursor, попробуйте наш бесплатный оптимизатор промптов. А для обзора лучших инструментов кодирования смотрите Claude Code vs Codex.
Это то, что мы делаем каждую неделю. Одна углублённая статья об инструментах AI, рабочих процессах и честных оценках — без хайпа, без наполнителя. Присоединитесь к нам →
Раскрытие информации: некоторые ссылки в этой статье — партнёрские ссылки. Мы рекомендуем только инструменты, которые мы лично тестировали и используем регулярно. Смотрите нашу полную политику раскрытия информации.