Предисловие. Microsoft и другие компании в последнее время выступают против паролей. Призывают использовать более безопасные и удобные методы 2FA. Среди альтернативных вариантов — авторизация через «волшебные ссылки», то есть через почтовый ящик.

Один разработчик попытался реализовать такую систему, но напоролся на совершенно неожиданное препятствие… Оказалось, кто-то ходит по приватным одноразовым ссылкам до пользователя — и авторизуется вместо него! Вы уже догадались, кто это.

Далее слово автору.


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

Как обычный ленивый девелопер, я быстренько сляпал простую систему токенов, которая работает по следующей схеме:

  1. Пользователь регистрируется, указывает свой адрес электронной почты (здесь ещё нужна Google Recaptcha).
  2. Генерируется уникальный токен, который отправляется по электронной почте в виде ссылки, которую можно нажать, подтвердить свой email и автоматически войти в систему.
  3. По истечении срока действия токен протухает (это я забыл реализовать, ну да ладно).

Такова базовая проверка электронной почты. Подобные схемы сейчас довольно популярны для реализации «волшебных ссылок», то есть входа в аккаунт без пароля. (Предполагается, что если у вас есть доступ к почтовому ящику, то наверное, ваша личность установлена. Ну а сам почтовый ящик максимально защищён, включая аппаратные токены, код на смартфон и прочее, так что «угнать» его очень сложно — гораздо сложнее, чем просто пароль от сайта).

Несколько недель всё нормально работало. Затем я вдруг заметил рост количества заходов в систему без каких-либо дальнейших действий на сайте. Очень странно.

Изучение логов показало: все фантомные входы генерирует Bingbot, то есть бот поисковой системы Bing от Microsoft!

Сначала я предположил, что это злонамеренная атака с поддельным юзер-агентом, но нет. IP-адреса злоумышленника совпадали с IP-адресами поисковой системы Bing, так что всё казалось законно.

Как Bing входил в аккаунты пользователей?


Ещё немного покопавшись, мне удалось найти конкретные токены. Все эти фейковые сессии начинались с URL с уникальным токеном, который я отправлял для верификации почты. Без реферера.

Единственным логичным объяснением было то, что Microsoft отправляла электронную почту из сервисы Outlook (со ссылками) в поисковую систему Bing для индексации. Все мы знаем, что провайдеры электронной почты собирают наши данные. Но, конечно, они не индексируют приватный контент электронной почты… Ведь правда, не индексируют?..

Быстро погуглив (потому что никто ведь не пользуется бингом), я нашел это:

С февраля 2017 года Outlook (https://outlook.live.com/) сканирует электронные письма, поступающие в ваш почтовый ящик, и отправляет все найденные URL-адреса в Bing, чтобы их проиндексировал краулер Bing.

Это фактически делает бесполезными все одноразовые ссылки, такие как логин, сброс пароля и т. д.

Мне показалось, что я наткнулся на заговор уровня Wikileaks. Неужели Microsoft передаёт приватное содержимое электронной почты в свою поисковую систему?

Чтобы поверить в столь невероятный заговор, нужно было проверить факты… и мои опасения подтвердились.

Bing действительно индексировал мои ссылки для верификации почтовых адресов


Bingbot автоматически переходил по этим ссылкам и автоматически входил в учётные записи новых пользователей.

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

Исправление


В качестве быстрого фикса я добавил функцию истечения срока действия токенов (теперь все токены истекают после использования и действительны только в течение 1 часа).

Но вероятно, придётся перейти к формату «вот ваш одноразовый код» (без ссылок), который пользователь должен вручную скопировать и вставить на страницу. Так спокойнее.

Несомненно, существует много других (лучших) способов повысить безопасность такого флоу. И обнаружить ботов в наши дни довольно просто, так что я мог бы добавить дополнительные проверки… Но когда узнаёшь, что любые конфиденциальные ссылки рискуют появиться в результатах поиска, то уже как-то не очень комфортно их использовать.



Примечание. В обсуждении на lobste.rs высказали предположение, что аналогичным образом поступают многие почтовые сервисы. Скорее всего, они ходят по ссылкам не для поисковой индексации, а для антивирусной проверки. Но в любом случае передавать конфиденциальную информацию по почте без шифрования — не самая лучшая идея. Ведь любое письмо открыто для индексации десятками автоматических сканеров на пути от отправителя к адресату.

Комментарии (32)


  1. Firz
    07.07.2022 12:33
    +10

    Призывают использовать более безопасные и удобные методы 2FA. Среди альтернативных вариантов — авторизация через «волшебные ссылки», то есть через почтовый ящик.

    По-моему лет 15 назад(ну 10 точно) такую проблему уже поднимали(только тогда гугл ходил по всем ссылкам в письме).
    Должна быть не волшебная ссылка на почту, а одноразовый код на почту(раз уж почта используется как второй фактор), который пользователь уже вводит как подтверждение где-то в интерфейсе приложения. То есть информация, пришедшая на почту, не должна быть единственно необходимой для авторизации(ткнул на ссылку(кто угодно) и авторизован), а должна содержать только какой-то ничего не значащий код, который нужно ввести в той сессии, где изначальный пользователь уже ввел свой первый фактор авторизации.


    1. Bromles
      07.07.2022 13:08

      Собственно, Firefox уже давно только так и авторизует пользователей


    1. Revertis
      07.07.2022 13:24

      Одна из причин настраивать себе свой собственный почтовый сервер. Чтобы никакие боты не ходили по ссылкам.


      1. Firz
        07.07.2022 13:39
        +3

        В данном случае проблема все же не в том что кто-то читает письма и ходит по ссылкам в них(но вообще это тоже проблема), а в дырявой механике авторизации(после ввода кем-то и где-то первого фактора авторизации(пароль), по сути отключает этот фактор и просто отправляет на почту ссылку для прямой авторизации в обход первого фактора), просто бот, ходящий по ссылкам, показал уровень дырявости этой механики.


        1. Revertis
          07.07.2022 13:57

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


          1. Firz
            07.07.2022 14:04

            Свой почтовый сервер хорошо, но если честно лень суетиться и периодически пытаться понять почему письма с твоего сервера у кого-то в спаме.
            Я обычно если вижу совсем дырявый сервис/механики в нем, либо пишу об этом(если прям очень нужен именно это сервис или нету аналогов), либо просто забивают и иду в нормальный.


            1. Revertis
              07.07.2022 14:11

              если честно лень суетиться и периодически пытаться понять почему письма с твоего сервера у кого-то в спаме

              Никогда такого не было за 10 лет использования своих серверов.


              1. AlexanderS
                07.07.2022 14:55

                Именно почтовых серверов? Мне вот интересно: какая за 10 лет потребовалась поддержка? Периодически же обновлять надо, а когда поддержка ОС прекращается, то нужно перебираться на следующую версию с сопутствующими возможными траблами при переходе.


                1. Revertis
                  07.07.2022 15:19

                  Да, именно их. Поддержка постоянная, конечно. То там подпилить, то там. Сначала был spamassassin с RBL, потом на Rspamd перешёл - тоже работа. Обновления ОС, конечно же, включая апгрейды версий - с дебиана 7 до 11. Но за это время и расположение менялось пару раз, разные VPS, теперь виртуалка дома.


                  1. AlexanderS
                    07.07.2022 15:50

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


                    1. Evengard
                      07.07.2022 19:30
                      +1

                      Мне лично нравится туториал https://123qwe.com/tutorial-debian-10/ - я по сути по ней свой почтовик поднял (с некоторыми доработками под себя, но тем не менее), описано вполне понятно что, куда и почему.


      1. iBuilder
        08.07.2022 21:03
        +1

        А толку от своего, если пользователь может использовать Outlook, который и сольет ссылки. Тут и почтовый клиент нужно проверять, что он с почтой делает.


        1. Revertis
          09.07.2022 02:18

          А, ну в этом плане я (почему-то) доверяю своему Roundcube.


  1. usrsse2
    07.07.2022 12:41
    +18

    По ссылке "Unsubscribe" он тоже сам переходит и отписывает от всех рассылок? Удобная функция)


    1. urvanov
      07.07.2022 12:43
      +6

      А заодно ещё по всем "Subscribe" тоже ходит и подписывается.


    1. ookami_kb
      07.07.2022 12:56
      +9

      Вот именно поэтому (в том числе) GET-запрос не должен ничего изменять.


    1. kahi4
      07.07.2022 13:29
      +1

      Видимо, именно поэтому каждый раз нужно на самой странице нажать кнопку «unsubscribe”.

      к слову, в том же аутлуке есть системная кнопка unsubscribe в самом приложении. Интересно, он заходит на страницу и жмакает кнопку, есть специальное апи для этого или он просто скрывает письма?


      1. Evengard
        07.07.2022 13:40
        +4

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

        Интерфейс именно для этого механизма эта кнопка и предоставляет.


  1. ifap
    07.07.2022 13:16
    +7

    В качестве быстрого фикса я добавил функцию истечения срока действия токенов

    О, мсье желает, чтобы его посетители соревновались в скорости реакции с ботом? Мсье знает толк в куртуазных развлечениях! Быстрый фикс это:

    RewriteCond %{HTTP_USER_AGENT} bingbot
    RewriteRule ^.* - [F]


    1. SergeyMax
      07.07.2022 15:02
      +1

      А для гуглового бота где быстрый фикс?


  1. shalamberidze
    07.07.2022 13:23
    +3

    Да эта проблема глобальнее. Любая система, принимаюшая ссылку делает гет запрос.

    Ктото скриншот делает, ктото еше как но смысл тот же. одноразовые ссылки уже проблема.

    ваибер, гмаил и много кто еше.


  1. mrk-andreev
    07.07.2022 14:06
    +5

    Проблема в непонимании принципов семантики Http. GET запрос не должен изменять состояние системы.


    1. shalamberidze
      07.07.2022 15:05
      +1

      Стандарты это хорошо но вот Вам пример, упрошенный но все же. Посылаете платежный линк. Гмаил прошел по нему и банковский софт открыл сессию. Потом зашел клиент и открылась вторая сессия.

      Никто ничего не менял ;)

      Клиент заплатил и в систему вернулось подтверждение. А на первую сессию идет отказ. Вот и думаи потом что и почему :) И приходится делать промежуточные линки и тому подобное.

      Я к тому что сканирование одноразовых ссылок добавляют головной боли независимо от следования стандартам.


      1. fougasse
        07.07.2022 22:15
        +3

        Вот поэтому никаких сессий на GET не должно «открываться».


        1. shalamberidze
          09.07.2022 16:35

          Вы путаете rest api и http


  1. Aleksandr-JS-Developer
    07.07.2022 14:20
    +6

    Как минимум:
    1. Ссылка с токеном
    2. Страница по ссылке
    3. На странице кнопка подтвердить (а лучше капча, а ещё лучше ещё раз первый фактор)
    4. При нажатии подтвердить (валидации введённых данных) - POST запрос


  1. knstqq
    07.07.2022 23:10

    а robots.txt настроены правильно на домене? Если robots.txt разрешают скачивать https://example.com/auth?... документы, то вебмастер сам себе редиска.

    Ну и как справедливо выше заметили, GET запрос не должен валидировать пользователя.


    1. stork_teadfort
      08.07.2022 08:59
      +1

      Это не тот бингбот, что странички индексирует. Это какой-то бот безопасности, который ссылки из писем на фишинг и малыарь проверяет и все такое. Robots.txt он, конечно же, игнорирует (что логично)


      1. ifap
        09.07.2022 12:56

        Изучение логов показало: все фантомные входы генерирует Bingbot, то есть бот поисковой системы Bing от Microsoft!


  1. v1000
    08.07.2022 10:34

    Bingbot автоматически переходил по этим ссылкам и автоматически входил в учётные записи новых пользователей.

    такое чувство что здесь было бы очень к месту “подтвердите, что вы не робот”?


  1. dimmount
    08.07.2022 13:37
    +1

    И гугл ходит и яндекс. И подверждают раньше пользователя все ссылки "На вашу почту отправлено... подтвердите". Пробовал сделать "длинную" ссылку с несколькими параметрами. Тогда почтовики считают её чем-то специфичным, куда ходить не надо (но это не точно, могут и сходить). Единственное рабочее решение - на конечной странице должен быть javascript, который возьмет данные из урла и отправит рестом на сервер.


    1. ookami_kb
      09.07.2022 13:46

      С чего это вдруг оно единственное? Выше уже привели рабочие решения:

      • не ломать семантику GET-запроса и использовать POST для подобных действий;

      • проверять User Agent.

      И оба этих решения лучше, чем костылить JS, который:

      1. Не будет работать у пользователя, если у него отключен JS.

      2. Не факт, что остановит бота. Бот вполне себе может поддерживать JS.