Риск: Высокий 8.5 High CWE-798: Use of Hard-coded Credentials

API-ключ во frontend-коде: какие ключи можно публиковать

В эпоху вайб-кодинга и ИИ-конструкторов (Lovable, Bolt.new, Cursor, v0) разработчики часто вызывают внешние API (OpenAI, Stripe, Anthropic, Telegram Bot API) напрямую из React или Vue компонентов.

Все переменные, скомпилированные сборщиком (Vite, Webpack, Next.js) в клиентский JS-бандл, становятся полностью публичными. Злоумышленник может скопировать секретный ключ и расходовать ваш баланс.

Степень критичности и чем опасна уязвимость

Секретные токены OpenAI (sk-...) или сервисные роли Supabase (service_role), утекшие во фронтенд, позволяют злоумышленникам слать миллионы запросов за ваш счет или полностью удалять таблицы пользователей.

Вектор атаки: Автоматизированные сканеры и поисковые ботнеты постоянно исследуют интернет по данной сигнатуре. При обнаружении уязвимости атака запускается в автоматическом режиме без участия человека.

Как наш сканер находит эту уязвимость

Сканер пассивно инспектирует подключенные скрипты фронтенда регулярными выражениями на сигнатуры токенов популярных провайдеров (OpenAI, Claude, Stripe, AWS, Supabase service keys).

В рамках сканирования конфигурационных файлов модуль Site Check отправляет легковесные изолированные HEAD- и GET-запросы с валидацией статус-кодов (404/403 vs 200). Запросы содержат стандартные маркеры безопасности и не сохраняют скачиваемые данные в постоянное хранилище, предотвращая несанкционированное распространение конфиденциальной информации.

Как устранить уязвимость (Пошаговое руководство)

Для ликвидации риска выполните следующие действия в конфигурации вашего сервера или приложения:

Перенос вызова приватного API на собственный бэкенд / Route Handler
      // НЕПРАВИЛЬНО (ключ утекает во фронтенд):
// const res = await fetch('https://api.openai.com/v1/...', { headers: { Authorization: `Bearer ${NEXT_PUBLIC_OPENAI_KEY}` } });

// ПРАВИЛЬНО (запрос через серверный эндпоинт):
const res = await fetch('/api/generate', { method: 'POST', body: JSON.stringify(data) });
    
  • Удалите приватные API-ключи из клиентских файлов и переменных окружения с префиксом PUBLIC.
  • Создайте серверный роут (/api/...) или Edge Function для защищенных запросов к внешним сервисам.
  • Инвалидируйте и перевыпустите скомпрометированные ключи в личных кабинетах провайдеров.

Анатомия атаки и реальные последствия для проекта

Вайб-кодеры часто просят ИИ добавить интеграцию OpenAI или Resend прямо в компонент React. В результате секретный токен жестко прописывается в коде и попадает в публичные скомпилированные чанки main.*.js. Сканеры выкачивают JS-бандлы, ищут регулярками паттерны sk-[a-zA-Z0-9]{48} и мгновенно исчерпывают баланс разработчика.

Финансовые и юридические риски: Исчерпание лимитов на счетах OpenAI, Stripe или Resend за считанные минуты, блокировка корпоративного аккаунта поставщиком API и финансовые убытки от несанкционированных вызовов.

Влияние на соответствие стандартам: Нарушение PCI-DSS Req 6.5.6 (управление криптографическими ключами) и требований безопасности OWASP API Security Top 10 (API2:2023 Broken Authentication).

Матрица эшелонированной защиты (Defense-in-Depth)

Уровень защиты Техническое действие Инструмент / Механизм
Архитектура фронтенда Вынос всех приватных API-вызовов на бэкенд или Serverless Edge функции (Next.js Actions, Astro Endpoints) API Proxy Layer
Управление ключами Строгое разделение публичных (pk_test_...) и приватных (sk_live_...) токенов Stripe / Cloudflare Workers
CI/CD сборщик Использование плагинов сборщика для запрета включения переменных окружения без префикса PUBLIC_ Vite / Webpack Enforce

Верификация устранения: команды для быстрой проверки

После внесения изменений в настройки сервера или исходный код приложения проверьте отсутствие уязвимости с помощью терминальных утилит:

Терминал: Проверка эндпоинта и заголовков ответа
curl -s https://ваш-домен.com/ | grep -oE "(sk-[a-zA-Z0-9]{20,}|AIza[0-9A-Za-z-_]{35})"
# Не должно быть вывода
    

Рекомендации DevSecOps для безопасного развертывания

Все вызовы сторонних API с приватными ключами должны происходить на сервере (Next.js Server Actions, Astro API Endpoints, Cloudflare Workers). Никогда не передавайте приватные токены в браузер.

Контрольный чеклист инженера безопасности:
  • ✓ Добавить шаблоны .env* и .git* в корень .gitignore и глобальный gitignore
  • ✓ Внедрить автоматический pre-commit хук gitleaks в локальный пайплайн разработки
  • ✓ Настроить регулярную ротацию скомпрометированных токенов API
  • ✓ Проверить конфигурацию веб-сервера на блокировку запросов к скрытым файлам

Часто задаваемые вопросы по устранению

Почему нельзя хранить ключ OpenAI во фронтенде, если он скрыт в коде?
Любой JavaScript-код выполняется в браузере клиента. Любой пользователь может открыть вкладку Network в инструментах разработчика и скопировать ключ из заголовка Authorization.
Как настроить безопасный прокси для вызова ИИ?
Создайте серверный эндпоинт (/api/generate), который принимает промпт от клиента, проверяет сессию и авторизацию, а затем обращается к OpenAI со своего сервера, используя приватный токен.
Экспертное резюме инженера по информационной безопасности

Утечки секретов и конфигурационных файлов представляют максимальную угрозу автоматизированного захвата инфраструктуры. Рекомендуется внедрить pre-commit хуки (GitLeaks, TruffleHog), вынести переменные окружения в защищённые хранилища секретов (HashiCorp Vault, Doppler, AWS Secrets Manager) и настроить в веб-сервере безусловный запрет отдачи скрытых файлов с точкой.

Для предотвращения вектора «API-ключ во frontend-коде: какие ключи можно публиковать» зафиксируйте проверочные правила в CI/CD пайплайне и настройте непрерывный мониторинг внешнего периметра через Site Check.