ТестированиеТестирование безопасностиИнженер по тестированию безопасности

Секретный ключ встроен в файл, который загружает браузер. Как доказать, что он не является секретом?

Секретный ключ встроен в файл, который загружает браузер. Как доказать, что он не является секретом?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

Если ключ предназначен только для идентификации приложения или имеет строго ограниченные публичные права, он может быть не секретом. Но настоящий секретный ключ должен оставаться на сервере или в другом доверенном компоненте.

Исторический контекст

Клиент-серверная модель разделяет доверенную серверную часть и клиент, которым управляет пользователь. Браузер получает HTML, скрипты и данные, поэтому пользователь может просматривать, сохранять и изменять всё, что доставлено клиенту.

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

Постановка проблемы

Если настоящий секрет встроен в клиентский файл, любой пользователь может извлечь его из исходного текста, сетевого ответа, карты исходников, кэша или памяти браузера. Затем ключ могут использовать вне приложения, например для обращения к API, подписания запросов или расходования квот.

Последствия зависят от полномочий ключа: от превышения лимитов до доступа к данным и административным операциям. Нельзя делать вывод о критичности только по названию переменной: необходимо проверить, какие серверные действия действительно разрешает этот ключ.

Подробное решение

Сначала получают все ресурсы, которые реально загружает браузер: HTML, скрипты, динамические чанки, файлы конфигурации и доступные карты исходников. Затем ищут значения, похожие на ключи, токены и пароли, включая строки, сформированные во время выполнения.

После обнаружения проверяют происхождение значения и его назначение. Важно установить, является ли оно публичным идентификатором, открытым ключом для проверки подписи или credential, который сервер принимает как доказательство полномочий. Для этого в безопасной тестовой среде выполняют минимальную разрешённую проверку с найденным значением и фиксируют, какие операции оно позволяет выполнить.

Нужно также проверить старые версии файлов в CDN, кэшах и артефактах сборки: удаление ключа из текущего файла не отзывает уже опубликованное значение. Если ключ был секретным, его необходимо отозвать и выпустить новый, а не просто удалить строку из исходников.

Надёжное исправление — перенести использование секрета на сервер. Браузер обращается к серверному endpoint, а сервер применяет ключ самостоятельно. Если прямой доступ из браузера необходим, используют специально публичный ключ или краткоживущий токен с минимальными полномочиями и серверными ограничениями; обфускация, ограничение CORS и проверка Referer не превращают секрет в защищённый.

Ситуация из практики

В клиентском бандле нашли ключ внешнего сервиса карт. Рассматривались три варианта: оставить ключ и скрыть его обфускацией, ограничить его по домену или перенести запросы на сервер.

Обфускация не защищает значение, поскольку браузер должен его восстановить. Ограничение по домену снижает риск злоупотребления, но не всегда предотвращает использование ключа напрямую и не заменяет отзыв скомпрометированного credential. Был выбран серверный прокси с ограничением операций и лимитами; ключ отозвали, выпустили новый и проверили, что старое значение больше не принимается.

Результат: браузер перестал получать настоящий секрет, а сервер контролирует допустимые операции, журналирование и ограничения нагрузки. Цена решения — дополнительный сетевой переход и необходимость защищать сам прокси от злоупотребления.

Что кандидаты часто упускают

  1. Достаточно ли спрятать ключ в минифицированном или обфусцированном файле?

Нет. Минификация изменяет читаемость, но не доступность значения: браузер получает данные и код, необходимые для работы приложения. Тестировщик может исследовать сетевые ответы, формат выполнения и поведение клиента, поэтому обфускация повышает стоимость анализа, но не создаёт секретности.

  1. Является ли любой ключ в клиентском приложении уязвимостью?

Нет. Публичный идентификатор приложения, открытый ключ для проверки подписи или специально ограниченный браузерный ключ могут быть рассчитаны на раскрытие. Уязвимость возникает, когда значение предоставляет полномочия, которые должны принадлежать только доверенной серверной стороне, либо когда его ограничения не соответствуют модели угроз.

  1. Достаточно ли удалить ключ из текущей версии приложения?

Нет. Опубликованные бандлы, карты исходников, CDN и браузерные кэши могут сохранять старое значение. Нужно определить период и область распространения ключа, отозвать его на стороне поставщика, проверить недействительность прежнего значения и только затем удалить его из исходников и артефактов.