Перейти к основному содержанию
Вход через мессенджер удобен, но подтверждение в чате ничем не связано с браузером, где откроется сессия: человек, которого уговорили подтвердить чужой QR-код, отдаёт вход атакующему. Passkey привязан к адресу вашего приложения и работает только рядом с браузером, поэтому обязательный ключ защищает от этого тех пользователей, у кого он есть. Veriqa остаётся способом входа и доставляет кнопку для заведения ключа, а регистрирует и проверяет ключ ваше приложение.
Механизмы для этого сценария в Veriqa уже есть, логику поверх них вы реализуете на своей стороне так, как удобно вам, — см. «Что вы реализуете сами».

Что Veriqa даёт passkey

Сам по себе passkey требует аккаунта, к которому его привязать, и способа вернуть доступ, если устройство с ключом потеряно. Когда вход идёт через Veriqa, и то и другое появляется с первым входом:
  • Аккаунт без формы регистрации. Первый вход через мессенджер даёт вашему приложению идентичность пользователя, и аккаунт вы создаёте по ней — без формы, пароля и подтверждения почты, как в сценарии «Вход и регистрация без пароля». Ключ добавляется к уже существующему аккаунту.
  • Резервный канал с первого входа. Аккаунт уже связан с мессенджером человека. Если устройство с ключом потеряно, у вас остаётся канал, через который можно связаться с человеком; восстановление через него ведите отдельной, более строгой процедурой (см. «На что обратить внимание»).
  • Меньше шагов, чем с формой регистрации. Чтобы войти, человек сканирует QR-код и нажимает кнопку в чате, а ключ заводит по ещё одной кнопке в том же чате.

Что вы реализуете сами

Veriqa passkey не создаёт и не проверяет: регистрацию и проверку ключа ведёт серверная библиотека WebAuthn вашего стека. Veriqa даёт вход и кнопку в мессенджере после него.
  1. Кнопка в мессенджере после входа. Задайте постдействие Redirect (или пункт-ссылку меню Menu) с адресом вашей страницы заведения ключа и {handle} в нём — Menu и Redirect:
    Пример синтетический: идентификатор клиента, адрес и подпись кнопки. Настройки лежат в записи клиента, поэтому кнопка приходит после каждого входа в это приложение через Telegram и только в чат того, кто подтвердил вход. Остальные каналы, которые показывают кнопки, добавьте в ту же карту.
  2. Страница заведения ключа. Ссылка из кнопки открывается там, где у человека мессенджер, — обычно на телефоне. Ваш сервер обменивает handle и узнаёт, кто вошёл (POST /api/link-handle/redeem с токеном приложения — см. «Два бота»), получает sub и запускает регистрацию WebAuthn для этого sub. Ключ создаётся на этом устройстве и привязан к адресу вашего приложения. Handle одноразовый и живёт Veriqa:TransactionEngine:CompletedRetentionSeconds — 600 секунд по умолчанию.
  3. Ключ — только по кнопке. Не давайте завести ключ из сессии, открытой входом через Veriqa: если вход был переслан, эта сессия у атакующего, и он завёл бы к чужому аккаунту свой ключ. Если у sub ключ уже есть, страница заведения регистрирует новый только после подписи существующим ключом: иначе атакующий, уговоривший человека подтвердить пересланный вход, попросит переслать и ссылку из кнопки и заведёт свой ключ.
  4. Ключ до сессии. Получив от Veriqa id_token, проверьте, есть ли у sub ключ. Если есть, запросите подпись ключа в этом же браузере и откройте сессию только после её проверки. Если нет — действуйте по своей политике: откройте обычную сессию или предложите завести ключ по кнопке в мессенджере.
  5. Обязательный режим. Для пользователя, который завёл ключ, вход без ключа закройте: пока он открыт, атакующий воспользуется им.

Почему это работает

Атакующий начинает вход в вашем приложении и пересылает QR-код жертве. Жертва подтверждает в своём мессенджере, и Veriqa отдаёт код авторизации браузеру атакующего. Дальше ваше приложение просит в этом браузере ключ жертвы. Страница-подделка на чужом адресе подписи для вашего адреса не получит, а вход ключом с телефона на чужой компьютер требует Bluetooth между ними: по RFC 10027 (BCP 247, §6.2.3.3) BLE нужен обоим устройствам. При обязательном ключе, если новые ключи добавляются только существующим, сессию атакующий не получит. В терминах BCP 247 для пользователей с обязательным ключом это близость устройств по радио (§6.1.1). Это и вход, устойчивый к фишингу, перед подтверждением, которое создаёт ваш сервер (§6.1.15). Как это соотносится с остальными мерами, показано на странице «Veriqa, BCP 247 и модель угроз».

На что обратить внимание

  • Защищает только обязательный режим. Пользователь без ключа или с открытым входом без ключа защищён не больше, чем обычным входом через мессенджер.
  • Заведение первого ключа — слабое место. Ссылка из кнопки действует на предъявителя: кто откроет её первым, тот и заведёт ключ к аккаунту, у которого ключа ещё нет. Атакующий, который уговорил человека подтвердить чужой вход, может попросить переслать и эту ссылку. Когда ключ у аккаунта уже есть, страница добавляет новый только после подписи существующим (шаг 3). Сообщайте пользователю о каждом новом ключе по каналу, который у вас есть, и давайте удалить чужой.
  • Нужен Bluetooth или ключ на самом компьютере. Вход ключом с телефона на компьютер требует Bluetooth на обоих устройствах. Где радио запрещено, работает ключ, созданный на самом компьютере: заведите первый ключ там, открыв кнопку, например, в настольном мессенджере. Если первый ключ уже на телефоне, на таком компьютере ключ не добавить: для этого нужна подпись существующим ключом, а ей тоже нужен Bluetooth. Тогда для такого периметра подходит фактор места.
  • Не во всех каналах есть кнопка. Кнопку после входа показывают мессенджеры и вход через аккаунт провайдера. Email кнопок не показывает, WhatsApp через Twilio их не отправляет: таким пользователям нужен свой путь к ключу, но не из сессии, открытой через Veriqa.
  • Потеря устройства. Восстановление доступа без ключа — ещё один путь в обход ключа. Ведите его отдельной процедурой, строже обычного входа, — см. «Восстановление доступа».