Счётчик посещаемости отправил бы наружу одноразовые токены, и увидеть это было бы негде
Внешняя аналитика шлёт адрес страницы целиком. У двух публичных адресов в адресе лежит секрет — подтверждение регистрации и сброс пароля. Поэтому список разрешительный.
Нам нужна была посещаемость сайта: сколько людей доходит до тарифов, что читают, откуда уходят. Ставим внешний счётчик — и упираемся в собственное обещание, написанное на том же сайте: «содержимое наружу не уходит».
Дальше выяснилось, что дело не только в обещании.
Настоящая причина
Счётчик отправляет адрес страницы целиком. А у нас есть два публичных адреса, в которых лежит одноразовый секрет:
- подтверждение регистрации —
?token=…; - сброс пароля —
?token=….
Счётчик, включённый «на все публичные страницы», отправил бы эти токены наружу. И увидеть это было бы негде: ни в одном интерфейсе такая отправка не видна, ни один журнал о ней не скажет, а поймать её можно только вкладкой «Сеть» в браузере в нужную секунду.
Это не утечка содержимого. Это утечка ключа от учётной записи — того, по которому сбрасывают пароль.
Почему список разрешительный, а не запретительный
Запретительный список требует помнить о секрете при каждой новой странице. Один раз забудете — и токен уедет.
Разрешительный отказывает всему незнакомому сам. Перечислены адреса витрины; всё, чего в списке нет, счётчика не получает, даже если страница публичная и безобидная. Цена — надо не забыть добавить новый раздел, и тогда он выйдет «немым»: трафик идёт, в отчёте ноль.
Эта цена оказалась ровно та, что нужно: забытая страница теряет статистику, а не отдаёт секрет. Забывчивость в одну сторону дешевле забывчивости в другую.
Границу держит проверка, а не договорённость
Список сам по себе — договорённость, а договорённости стираются при спешке. Поэтому его читает гейт в общем прогоне, и он ловит два разных нарушения:
- внешний скрипт, оказавшийся за периметром — в рабочей части, на витринах проектов, на страницах по секретной ссылке;
- страницу с токеном в адресе, попавшую в разрешительный список.
Второе — как раз то, что человек в ревью не заметит: путь выглядит обычным.
Как проверить у себя
Если ваша студия ставит клиентам счётчики — посмотрите, не бывает ли в адресах их страниц одноразовых ссылок. Приглашения, подтверждения, сброс пароля, ссылки «посмотреть заказ» из письма, ссылки на скачивание.
# самый быстрый признак: параметры, похожие на секрет, в путях сайта
grep -rnE "\?(token|key|hash|code|invite)=" .
Дальше — открыть такую страницу с включённым счётчиком и посмотреть, что уходит в запросе счётчика. Проверка занимает минуты, а утечка не видна никому.
Что из этого следует
Правило шире аналитики: всё, что отправляет наружу адрес страницы, отправляет и то, что в адресе лежит. Счётчики, виджеты чатов, реферер при переходе по внешней ссылке, картинки с чужого домена.
Значит, решение принимается не про счётчик, а про адреса: секрет в адресе — это секрет, который увидит любой сторонний скрипт на странице. Если так делать приходится, страница обязана быть исключена из всего внешнего явно, и исключение обязано проверяться машиной.
Витрины проектов у нас закрыты от внешних скриптов целиком: там документы заказчика, и никакой статистики оттуда наружу не уходит. Как устроены витрины — Клиентский портал.
Читайте также
Автор
Александр ЦапковОснователь Скоупворк
Веду платформу и её боевой контур сам: разработка, выкат, дежурство. Пишу о том, на чём мы обожглись, — с датами, замерами и ссылками на решения в репозитории.