Как мы строим

Счётчик посещаемости отправил бы наружу одноразовые токены, и увидеть это было бы негде

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

Александр Цапков10 сентября 20263 мин

Нам нужна была посещаемость сайта: сколько людей доходит до тарифов, что читают, откуда уходят. Ставим внешний счётчик — и упираемся в собственное обещание, написанное на том же сайте: «содержимое наружу не уходит».

Дальше выяснилось, что дело не только в обещании.

Настоящая причина

Счётчик отправляет адрес страницы целиком. А у нас есть два публичных адреса, в которых лежит одноразовый секрет:

  • подтверждение регистрации — ?token=…;
  • сброс пароля — ?token=….

Счётчик, включённый «на все публичные страницы», отправил бы эти токены наружу. И увидеть это было бы негде: ни в одном интерфейсе такая отправка не видна, ни один журнал о ней не скажет, а поймать её можно только вкладкой «Сеть» в браузере в нужную секунду.

Это не утечка содержимого. Это утечка ключа от учётной записи — того, по которому сбрасывают пароль.

Почему список разрешительный, а не запретительный

Запретительный список требует помнить о секрете при каждой новой странице. Один раз забудете — и токен уедет.

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

Эта цена оказалась ровно та, что нужно: забытая страница теряет статистику, а не отдаёт секрет. Забывчивость в одну сторону дешевле забывчивости в другую.

Границу держит проверка, а не договорённость

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

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

Второе — как раз то, что человек в ревью не заметит: путь выглядит обычным.

Как проверить у себя

Если ваша студия ставит клиентам счётчики — посмотрите, не бывает ли в адресах их страниц одноразовых ссылок. Приглашения, подтверждения, сброс пароля, ссылки «посмотреть заказ» из письма, ссылки на скачивание.

# самый быстрый признак: параметры, похожие на секрет, в путях сайта
grep -rnE "\?(token|key|hash|code|invite)=" .

Дальше — открыть такую страницу с включённым счётчиком и посмотреть, что уходит в запросе счётчика. Проверка занимает минуты, а утечка не видна никому.

Что из этого следует

Правило шире аналитики: всё, что отправляет наружу адрес страницы, отправляет и то, что в адресе лежит. Счётчики, виджеты чатов, реферер при переходе по внешней ссылке, картинки с чужого домена.

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


Витрины проектов у нас закрыты от внешних скриптов целиком: там документы заказчика, и никакой статистики оттуда наружу не уходит. Как устроены витрины — Клиентский портал.

Клиентский портал документации с паролем на входИз выбранных документов собирается портал для заказчика на адресе проекта.

Читайте также

Автор

Александр ЦапковОснователь Скоупворк

Веду платформу и её боевой контур сам: разработка, выкат, дежурство. Пишу о том, на чём мы обожглись, — с датами, замерами и ссылками на решения в репозитории.