3 сентября в сеть выложили 550 ГБ данных Manchester Airports Group. По заявлению атакующих, вход дали ключи администратора, лежавшие в JavaScript сайтов. Внутри: 6 мест, где секреты оказываются на виду, проверка своего сайта за 20 минут и порядок действий, если ключ нашелся.
550 ГБ данных, 8,8 млн адресов и телефонов, 108 тыс. автомобильных номеров. Точка входа, по заявлению взломщиков, — ключи администратора, лежавшие в JavaScript на главных страницах его сайтов.
Это история Manchester Airports Group, опубликованная SecurityWeek 3 сентября 2026 года. Масштаб тут вторичен. Интересна банальность причины. Секрет в коде фронтенда — это не экзотическая уязвимость и не нулевой день. Это обычная строчка, которую разработчик написал, чтобы «пока работало», и которая уехала в продакшен вместе со сборкой.
Проверить свой сайт на такие ключи можно за 20 минут, без пентеста и без подрядчика. Ниже — где именно они прячутся, чем проверить и что делать, если нашли.
Что произошло в Манчестере
Manchester Airports Group управляет аэропортами Манчестера, Лондон-Станстеда и
MAG подтвердила 2 вещи: украденные данные хранились в базе, размещенной у стороннего подрядчика, и компания получила требование выкупа. Платить отказались. В первые выходные сентября группировка FulcrumSec взяла ответственность на себя и выложила примерно 550 ГБ данных.
Сервис Have I Been Pwned разобрал массив и добавил его в базу: около 8,8 млн адресов почты и телефонов, плюс имена, данные браузера, покупки и автомобильные номера. Сама группировка заявляет о 2 482 763 покупках, 461 433 SMS, привязанных к бронированиям, и 108 077 уникальных британских номерных знаков.
Способ проникновения FulcrumSec описывает буквально: административные ключи лежали «на виду, во
Что считается секретом
Секрет — это любая строка, которая сама по себе дает доступ. Пароль от базы, токен API, ключ доступа к облачному хранилищу, приватный ключ сертификата, подпись вебхука, сервисный аккаунт, ключ платежного шлюза с правом списания.
Главное свойство секрета: он работает у любого, кто его держит. Сервис на другом конце не отличает запрос вашего сайта от запроса человека, скопировавшего ключ из исходников.
Отсюда правило, которое нарушают чаще всего. Все, что отдается браузеру, — публично. Минификация не прячет: строку видно поиском по файлу. Обфускация не прячет: ключ все равно должен быть в открытом виде в момент запроса. Переменная с именем window.__INTERNAL_KEY не становится внутренней оттого, что так названа.
Есть класс ключей, которые в браузере находиться обязаны: публичный ключ Яндекс Карт, идентификатор счетчика аналитики, публичный ключ платежной формы. Они и рассчитаны на публичность, у них урезаны права и обычно есть привязка к домену. Признак нормального публичного ключа простой: в документации вендора написано, что его можно размещать на странице, и он не умеет ничего, кроме чтения.
Где секреты оказываются на виду: 6 типовых мест
По нашей практике в проектах поддержки почти все находки укладываются в этот список.

- Сборка фронтенда. Современные сборщики подставляют переменные окружения в код на этапе сборки. Если переменная названа так, что попадает в публичный префикс, ее значение уезжает в бандл. Разработчик видит у себя
.env, а пользователь — готовую строку в скачанном файле. - Инлайновый скрипт в шаблоне. Токен интеграции, вписанный прямо в
<script>в шапке сайта, — классика при подключении сторонних сервисов на скорую руку. - Карты исходников. Файлы
.map, выложенные рядом со сборкой, восстанавливают исходный код со всеми комментариями и именами переменных. Иногда там лежит то, чего нет в минифицированном виде. - Служебные файлы в корне сайта.
.env,config.php.bak,dump.sql, папка.git. Ни один из них не должен отдаваться по HTTP, новеб-сервер по умолчанию отдает все, что лежит в его корне. - История репозитория. Ключ добавили, через день убрали, но коммит остался. Если репозиторий
когда-либо был публичным или у него есть форки, ключ считается скомпрометированным навсегда. - Подрядчики и сторонние системы. В истории MAG база лежала у третьей стороны. Ваш ключ может утечь не через ваш сайт, а через сервис, которому вы его выдали.
Отдельная строчка про /bitrix/php_interface/dbconn.php в версиях до 20.900.0 и в /bitrix/.settings.php начиная с нее. Опасны не сами файлы — PHP их не отдает, — а их копии: dbconn.php.bak, .settings.php.old, dbconn.txt. Расширение изменилось, и
Проверка своего сайта за 20 минут
3 действия, для которых не нужен ни пентест, ни специальные права.
Шаг 1. Посмотрите, что скачивает браузер. Откройте сайт, нажмите F12, вкладка Sources или Network. Скачайте главный secret, token, api_key, apiKey, password, Bearer, AKIA, sk_live, -----BEGIN. Находки читайте глазами: половина совпадений окажется именами полей без самих значений.
Шаг 2. Постучитесь в служебные файлы. Все они должны отвечать 403 или 404. Ответ 200 — это находка.
SITE=https://example.ru
for p in .env .env.local .git/config .git/HEAD config.php.bak \
dump.sql backup.zip .settings.php.bak composer.lock \
bitrix/php_interface/dbconn.php.bak; do
code=$(curl -s -o /dev/null -w "%{http_code}" "$SITE/$p")
echo "$code $SITE/$p"
done Шаг 3. Проверьте историю репозитория. Git умеет искать по содержимому всех коммитов, включая давно удаленные строки.
# Ищем строку во всей истории проекта
git log -p -S 'api_key' --all | head -n 60
# Список файлов, которые когда-либо назывались .env
git log --all --diff-filter=A --name-only --pretty=format: | sort -u | grep -E '\.env|\.pem|\.key$' Если по итогам 3 шагов ничего не нашлось — это хороший результат, но не повод останавливаться: см. раздел про процесс ниже. Если нашлось — дальше по порядку.
Нашли ключ. Первые 2 часа
Порядок здесь важнее скорости, и первый шаг не тот, который просится.

Первое: отзовите и перевыпустите ключ. Не удаляйте строку из кода, не переписывайте историю коммитов, не думайте о том, кто виноват. Пока старый ключ действителен, все остальное бессмысленно. Ротация занимает минуты, и только она реально закрывает дыру.
Второе: посмотрите логи сервиса, к которому ключ давал доступ. Нужны нетипичные обращения: чужие IP, всплески запросов, выгрузки больших объемов, обращения ночью. Это единственный способ понять, воспользовались ключом или нет.
Третье: закройте саму причину. Ключ из браузера убирается не удалением строки, а переносом вызова на сервер: страница обращается к вашему же эндпоинту, а тот уже ходит во внешний сервис со своим ключом. Обычно это небольшая доработка сайта на несколько часов; переписывать фронтенд целиком не требуется.
Про удаление коммита стоит сказать отдельно, потому что на него надеются. Переписывание истории не помогает: копии остаются у всех, кто делал клон, в форках, в кеше хостинга репозиториев, в артефактах сборки и в логах CI. Утекший ключ не становится обратно секретным. Его можно только заменить.
Как закрыть это на уровне процесса
Разовая проверка ловит то, что уже есть. Чтобы не появлялось новое, нужны 4 вещи, и все они настраиваются за один день.
Запрет на отдачу служебных файлов
# Скрытые файлы и служебные расширения не отдаются никогда
location ~ /\.(env|git|svn|ht) { deny all; return 404; }
location ~* \.(bak|old|orig|sql|log|zip|tar|gz|sw[op])$ { deny all; return 404; } Секреты вне корня сайта. Файл с паролями лежит уровнем выше public_html или передается через переменные окружения процесса. Внутри репозитория — только шаблон .env.example с пустыми значениями.
Автоматическая проверка на стороне репозитория. У GitHub есть защита пуша: сканер распознает известные форматы токенов и блокирует отправку, а для публичных репозиториев она включена по умолчанию. У нее есть ограничение, о котором честно написано в документации: она не спасает, если приватный репозиторий делают публичным.
Разделение прав и срок жизни. Ключ, который умеет только читать каталог, при утечке стоит несравнимо дешевле ключа с правом списания денег. Плановая ротация раз в квартал делает украденный полгода назад токен бесполезным. В
Что требует закон, если данные все-таки утекли
Для российского оператора персональных данных сроки жесткие. По части 3.1 статьи 21 закона
Логика надзора устроена так, что наказывают не за сам инцидент, а за молчание и просрочку: если оператор уложился в сроки и может показать, что предпринял, позиция у него принципиально другая, чем у того, кто попытался инцидент скрыть.
Практический вывод: кто именно у вас обнаруживает утечку и кто в этот же день пишет уведомление — это решается заранее и записывается в регламент. Сутки — очень мало, если начинать с вопроса «а кто у нас этим занимается».
Частые вопросы
Мой сайт маленький, кому он нужен?
Открытые ключи находят не адресным взломом, а массовым сканированием: боты перебирают типовые пути вроде /.env по всем доменам подряд. Размер бизнеса тут не имеет значения, значение имеет только код ответа сервера. Логи любого сайта показывают такие запросы ежедневно.
Если ключ лежит в приватном репозитории, это безопасно?
Приватность репозитория — это контроль доступа, а не защита секрета. Доступ есть у подрядчиков, у бывших сотрудников до отзыва прав, у систем сборки. Кроме того, репозиторий может стать публичным по ошибке, и в этот момент вся история окажется открытой сразу.
Чем отличается публичный ключ карт от секретного токена?
Правами и намерением вендора. Публичный ключ рассчитан на размещение на странице, у него есть привязка к домену и он не умеет менять данные. Секретный токен умеет выполнять действия от вашего имени, и его место только на сервере. Если в документации не написано прямо, что ключ можно публиковать, считайте, что нельзя.
Мы нашли ключ, но им явно никто не пользовался. Можно оставить?
Нет. Отсутствие следов в логах не доказывает, что ключ не скопирован: его могли сохранить сегодня, а применить через полгода, когда про инцидент забудут. Ротация стоит 10 минут, разбор последствий — несоизмеримо дороже.
Как часто нужно перепроверять сайт?
Разово — прямо сейчас и полностью. Дальше — после каждого релиза, затрагивающего сборку фронтенда или подключение нового внешнего сервиса, и раз в квартал планово вместе с остальными проверками технического аудита.
Что сделать сегодня
Откройте свой сайт, скачайте главный файл сборки и поищите в нем 5 слов из шага 1. Прогоните скрипт из шага 2 по служебным путям. На это уйдет меньше получаса, и в половине случаев результат будет скучным — это лучший из возможных исходов.
История MAG стоила компании 550 ГБ опубликованных данных и 8,8 млн пострадавших записей. Причиной, по заявлению атакующих, была строка в файле, который сайт сам отдавал каждому посетителю.


