Избавляемся от паролей

Приветствую читателей Хабра! Меня зовут Александр Чикайло, я разрабатываю межсетевой экран уровня веб-приложений PT Application Firewall в Positive Technologies и специализируюсь на защите веба. Сегодня речь пойдет о беспарольной аутентификации и ее безопасном применении в приложениях. В этом материале я освещу систему passwordless-аутентификации, уже работающую «из коробки», например, в Windows 11 и Chrome.

В скобках замечу, что многие пока путают аутентификацию с авторизацией. Если упрощенно, аутентификация случается, когда я доказал, что я это я. Авторизация немного другое — это предоставление определенных прав для осуществления изменений в системе.  

История аутентификации на одном слайде

История аутентификации на одном слайде

Ненадолго углубимся в историю компьютерных паролей. В 1961 году Фернандо Хосе Корбато — американский ученый, сотрудник Массачусетского вычислительного центра — разработал первую систему компьютерных паролей. ПК тогда было мало, время их использования было ограничено, и Корбато выдавал каждому пользователю его пароль. В то время пароли хранились в открытом виде на листочке.

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

В 80-х, 90-х и нулевых были придуманы OTP (One Time Password — одноразовый пароль), технология единого входа (англ. Single Sign-On) SSO и мультифакторная аутентификация (MFA).

Несмотря на многочисленные трюки с паролями, долгое время уровень защищенности не сильно отличался от 1961 года, разве что злоумышленнику приходилась тратить чуть больше времени на взлом. В ранние 2010-е появилась биометрическая, а в поздние 2010-е — поведенческая аутентификация. 

В 2013 году образовался альянс FIDO (от англ. Fast Identity Online — быстрая онлайн-идентификация), в который входят более 250 организаций. Его цель — полный и повсеместный отказ от паролей. В 2014 году эксперт Gartner Авива Литан говорила, что пароли умерли еще несколько лет назад. Но они живы до сих пор, спустя 10 лет.

Что такое беспарольная аутентификация

Passwordless authentication означает, что пользователь может подтвердить доступ к приложению или IT-системе, не предоставляя пароль и не отвечая на секретные вопросы. К беспарольным методам относится, например, биометрия (вход в систему по отпечатку пальца, сердцебиению, походке, клавиатурному почерку, сетчатке, голосу, лицу и так далее). 

Какая бывает биометрическая аутентификация

Какая бывает биометрическая аутентификация

Варианты биометрической аутентификацииБеспарольная аутентификация может быть также по QR-коду (как в Telegram) или с помощью push-сообщения. Если мы пытаемся войти в Gmail и уже залогинены в телефоне, то нам прилетит «пуш» для подтверждения того, что мы это мы.

Аутентификация по QR-коду (как в Telegram) или с помощью push-сообщения

Аутентификация по QR-коду (как в Telegram) или с помощью push-сообщения

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

Что же не так с паролями?

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

Более миллиона долларов выплатили на HackerOne исследователям проблем аутентификации за год

Более миллиона долларов выплатили на HackerOne исследователям проблем аутентификации за год

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

Ниже в левой части графика мы видим практически непрерывный рост количества CVE-уязвимостей по ключевым словам plain text, brute force и «проблема с аутентификацией» (данные за середину 2023 года, поэтому в 2023 году уязвимостей меньше).

Число CVE-уязвимостей по ключевым словам plain text, brute force и «проблема с аутентификацией» неуклонно растет

Число CVE-уязвимостей по ключевым словам plain text, brute force и «проблема с аутентификацией» неуклонно растет

Как принято обходить веб-аутентификацию

У OWASP в «Руководстве по тестированию веб-безопасности» (Web Security Testing Guide, WSTG) перечислены 11 пунктов, касающихся тестирования защищенности веб-приложений. Для полноты картины добавим еще четыре подсказки из OWASP Authentication Cheat Sheet, которые не пересекаются с WSTG. Самая большая боль для специалистов — это, наверное, Default Credentials (пароли, используемые по умолчанию, или инженерные пароли).

Рекомендации OWASP по тестированию проблем аутентификации в веб-приложениях

Рекомендации OWASP по тестированию проблем аутентификации в веб-приложениях

Первый блин в виде SRPP

Одна из попыток прийти к passwordless была связана с Secure Remote Password Protocol (SRPP). На сервер в данном случае улетает соль, верификатор и логин, что позволяет пользователю хранить пароль в браузере, используя только логин. Однако пароль в этой схеме аутентификации все же используется, несмотря на применение доказательства с нулевым разглашением (zero-knowledge proof). А значит, сохраняются и недостатки: возможность фишинга, атаки на повторяющиеся пароли (password reuse) и так далее.

Secure Remote Password Protocol (SRPP) уязвим для фишинга

Secure Remote Password Protocol (SRPP) уязвим для фишинга

Настоящая беспарольность в виде WebAuthn

Следом появился стандартизированный механизм веб-аутентификации — WebAuthn. Он позволяет аутентифицироваться без паролей, так как их здесь в принципе нет. Тут взаимодействуют следующие участники: наше приложение и его бэкенд, фронтенд и аутентификатор. При этом аунтентификатор может быть платформенным (например, Windows Hello) или аппаратным — в виде бесконечного количества токенов. Схему генерации токенов можно найти в Сети или запрограммировать самому. Также для создания WebAuthn-приложения можно воспользоваться инструкцией Google.

Далее в таблице можно посмотреть, какие браузеры поддерживают WebAuthn. Красный цвет — отсутствие поддержки, зеленый — полная совместимость, а горчичный — частичная поддержка.

Какие браузеры поддерживают WebAuthn

Какие браузеры поддерживают WebAuthn

Как работает WebAuthn

Процесс регистрации для беспарольной аутентификации — это ввод имени пользователя на сайте. Затем эти данные отправляются на бэкенд, там генерируется JSON (слева на схеме ниже, PublicKeyCredentialCreationOptions) — это будет нужно в дальнейшем для создания JS-объекта и передачи его в аутентификатор. В этот JSON входят хеш origin нашего приложения, challenge. Мы получили эти данные, JS создает объект и отправляет запрос на аутентификатор. Аутентификатор генерирует пару ключей, причем приватный ключ он хранит внутри себя. Параметр challenge, подписанный этим приватным ключом, аутентификатор отдает обратно в браузер, и браузер формирует объект, которой передает обратно на наш бэкенд. 

Приведем пример процесса регистрации при использовании WebAuthn.

Регистрация клиента WebAuthn

Регистрация клиента WebAuthn

На скриншоте — код, который отправляет клиентское приложение, и ответ ему со стороны бэкенда. Большой блок в центре кода в правой части — настройки алгоритмов.

Регистрация клиента WebAuthn, первый запрос и ответ

Регистрация клиента WebAuthn, первый запрос и ответ

Второй запрос происходит после того, как мы получили все данные от аутентификатора. Он сообщил, что мы — это мы и имеем право залогиниться. В верхнем блоке в бинарном виде записаны origin, сигнатура, хеш, подписанный сhallenge и счетчик подписей, который выставляет аутентификатор. Если этот счетчик подписей скопировать и сверить с тем, что есть на бэкенде, и данные не сойдутся, значит, аутентифицироваться пытается нелегитимный пользователь.

Регистрация клиента WebAuthn, второй запрос и ответ

Регистрация клиента WebAuthn, второй запрос и ответ

Процесс аутентификации не сильно отличается от привычной схемы. Мы вводим логин, и он улетает на бэкенд. Там по id имени пользователя вытаскивают PublicKeyCredentialCreationOptions — параметр, хранящийся и на бэкенде, и в аутентификаторе. Далее это все собирается в JSON, отдается в браузер, JS собирает объект и кидает запрос на аутентификацию в наш аутентификатор. Он все проверяет, просит нас отсканировать палец, дотронуться до устройства (как в случае YubiKey) или ничего не делать. Подписал, вернул, сервер верифицирует все подписи, проверяет значение origin, которое тоже хранится в ответе аутентификатора. Если все хорошо — значит мы залогинились. 

Аутентификация клиента в WebAuthn

Аутентификация клиента в WebAuthn

Большой разницы в запросах и ответах нет: clientData вместо createGet и отличие в signature, где хранится подписанный сhallenge. А в поле userHandle хранится наш пользователь.

Аутентификация клиента в WebAuthn

Аутентификация клиента в WebAuthn

Настройка WebAuthn

Продемонстрируем, как сконфигурировать нашу беспарольную аутентификацию. Надо ввести два поля: user name и display name. Затем остается добавить платформозависимый аутентификатор, в нашем случае Windows Hello. Все, мы зарегистрированы, и нам не нужны никакие пароли. Это система аутентификации работает «из коробки» как минимум в Windows 11 и в современных редакциях Google Chrome.

Настраиваем WebAuthn

Настраиваем WebAuthn

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

Еще немного настроек

Еще немного настроек

Для тех случаев, когда нам важно, кто пришел в приложение (например, в банке), можно добавить обязательный запрос информации о токене в поле Attestation conveyance preference. То есть мы можем получить версию, модель и другие параметры токена и одобрить использование только сертифицированных в FIDO Alliance Metadata Service токенов.

Здесь можно добавить обязательный запрос информации о токене в поле Attestation conveyance preference

Здесь можно добавить обязательный запрос информации о токене в поле Attestation conveyance preference

Чуть ниже — варианты для выбора аутентификаторов. Первый — это платформозависимый аутентификатор, привязанный к платформе (on bound (platform) authenticator). В Windows это Hello, в Linux по умолчанию его нет. Другой вариант — кроссплатформенный аутентификатор. Это аппаратный аутентификатор, например смартфон или специальная флешка с биометрическим сенсором (например, YubiKey). Они позволяют отличить легитимного пользователя от программного бота, укравшего токен.

В Windows Hello, если вы не боитесь скармливать Windows свою биометрию, беспарольная аутентификация работает «из коробки», без дополнительных устройств. Замечу, впрочем, что YubiKey спокойно работает с Linux, а также со всеми видами виртуальных машин, с которыми я встречался (VirtualBox, VMware, Proxmox).

Варианты для выбора аутентификаторов

Варианты для выбора аутентификаторов

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

Приведу пример работы этой аутентификации в Chrome и Android. Если я залогинен под той же учетной записью, что и в Android,   аутентификатор предложит создать учетную запись с помощью смартфона — в данном случае RMX3581. При выборе другого телефона система предлагает отсканировать QR-код, после чего на экране смартфона появляется окошко, предлагающее создать учетную запись.

QR-код при выборе другого смартфона

QR-код при выборе другого смартфона

В Google Chrome есть программный эмулятор WebAuthn — можно его создать и посмотреть, что в нем хранится. Это id «кредов», который мы скормим в аутентификатор, а также user name, алгоритм и публичный ключ. Даже если атакующие получат доступ к этим данным, это не поможет им аутентифицироваться.

Программный эмулятор WebAuthn в Google Chrome

Программный эмулятор WebAuthn в Google Chrome

Если у нас нет пароля, мы его не потеряем и он не будет скомпрометирован, поэтому благодаря WebAuthn часть атак, перечисленных в первой части этого материала, отваливается. 

Какие проблемы в списке OWASP закрывает беспарольная аутентификации WebAuthn

Посмотрим еще раз на список WSTG (Web Security Testing Guide) и на то, как WebAuthn справляется с проблемами, упомянутыми в нем.

Какие проблемы в списке WebAuthn закрывает WebAuthn

Какие проблемы в списке WebAuthn закрывает WebAuthn

  1. Передача паролей по незашифрованному каналу не работает, так как для функционирования WebAuthn нужен исключительно протокол HTTPS.

  2. Нет паролей, значит нет и дефолтных учетных записей. Конечно, можно выстрелить себе в ногу и для тестирования добавить обходной путь, а потом его забыть и «задеплоить».

  3. Слабый механизм блокировки тоже зачеркиваем. Нет смысла что-то блокировать, когда нечего брутфорсить. 

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

  5. Нет пароля — значит не нужно его восстанавливать.

  6. С уязвимостью браузерного кэша, к сожалению, ничего сделать нельзя.

  7. Слабая парольная политика нас не беспокоит: паролей нет.

  8. Угроза эксплуатации секретных вопросов сохраняется: токен или ключ можно утратить. Может также пропасть или сломаться компьютер, где была создана учетная запись WebAuthn.

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

  10. Тут речь идет о каналах аутентификации, альтернативных вебу. WebAuthn заточен под веб и поэтому не особо применим к этому пункту.

  11. MFA-аутентификация сама по себе — достаточно защищенная технология, хотя и не полностью.

Теперь рассмотрим советы для пентестеров и веб-разработчиков OWASP Cheat Sheet. Напомню: выбранные четыре пункта относятся к веб-аутентификации и не дублируют рекомендации из OWASP WSTG. Насколько хорошо беспарольная аутентификации WebAuthn закрывает эти проблемы?

  1. OWASP советует рассмотреть возможность строгой аутентификации (в том числе использование двухфакторной аутентификации). Но если нет паролей, то нет проблем с их слабостью. Webauthn не подвержен этой проблеме.

  2. Эксперты рекомендуют включать повторную аутентификацию для конфиденциальных операций. Это помогает снизить вероятность реализации межсайтовой подделки запроса (Cross-site request forgery). Актуально ли это для WebAuthn? В общем случае, если пользователь авторизован в каком-то личном кабинете (например, банка) и нет защиты от CSRF, злоумышленник может сформировать страничку, заманить на нее пользователя и послать из его браузера запрос в личный кабинет от имени пользователя. Но если применяется WebAuthn, причем корректно, тогда для атаки потребуется совершить некоторые дополнительные действия от имени жертвы: воткнуть токен в USB или аутентифицироваться по отпечатку пальца. Для этого необходима социальная инженерия, что сильно затрудняет атаку.

  3. Автоматические атаки, иначе говоря брутфорс, не сработают: брутфорсить в WebAuthn нечего.

  4. Использование паролей в открытом виде (Plain Text) тоже отпадает, так как с публичным ключом в WebAuthn ничего нельзя сделать, механизм Webauthn защищен ассиметричным шифрованием.

Как можно заметить, WebAuthn решает многие, но не все проблемы защищенности аутентификации.

Почему WebAuthn не серебряная пуля

6c3c8a059115370a542e724fd75ff639.png

Этой проблемы я коснулся чуть выше: разработчики могут пойти по обходному пути и забыть про WebAuthn. Была такая история, что мы нашли локальную читалку файлов. В исходниках все было великолепно с точки зрения ИБ, кроме одной маленькой функции: почти все SQL-запросы экранировались, но в одном месте логин и пароль размещались в запросе в первозданном виде. В дальнейшем это позволило бы залить шелл-код и получить полный доступ к приложению. 

Кроме того, если злоумышленник получил доступ в базу, он может создать своего пользователя с нашим токеном и скопировать все данные, кроме username, а затем войти в административный аккаунт с этим токеном.

Как правило, самая большая проблема WebAuthn — в восстановлении токена, если доступ будет утрачен. Но есть обходной путь: дать пользователю создать несколько токенов для одной учетной записи. В этом случае, конечно, возникает проблема управления этими токенами в приложении, но она не такая сложная, как та, что возникает при потере единственного токена.

Хотите узнать больше? Полезные ссылки по теме WebAuthn:

313c4011e0bd92b918fc8e35d46246e6.jpgАлександр Чикайло

Старший специалист группы экспертизы защиты приложений Positive Technologies.

© Habrahabr.ru