Современный механизм авторизации через почту/пароль поощряет пользователя на опасные привычки и в безопасной версии (с 2FA) сложен в использовании.
ИТ-миру нужно больше обсуждения механизмов авторизации, чтобы прийти к более удобный и безопасным вариантам.
Это предложение содержит необычный формат авторизации для узкого круга задач. Какие ошибки в нём могуть быть в плане безопасности и удобства использования?
RSS-читалка, которая работает полностью локально (local first) использую облако только для синхронизации данных между клиентами:
- Будет использоваться ежедневно, часто и с ноутбука, и с телефона.
- Данные (список подписок) потерять не хочется, но они не критичные.
- Будет использоваться пользователями с разным техническим уровнем.
- Сервер не должен ничего знать о пользователе.
- Сервер и клиент будет опенсорсными, чтобы можно было проверить код (на 100% доверять можно только коду клиента).
На лэндинге будет две кнопки: «Войти» и «Попробовать без регистрации».
При выборе Попробовать, клиенту присвоится случайный userId
и загрузиться обычный UI, который будет сохранять данные локально.
В верхнем меню сразу будет предупреждение, что надо бы зарегистрироваться, чтобы иметь доступ с разных устройств.
По клику на Регистрация, мы генерируем ключ авторизации и ключ шифрования.
Получаем длинный общий ключ
${ userId }-${ accessSecret }-${ encryptionSecret }
.
Мы спрашиваем пользователя, есть ли у него менеджер паролей (в сноске рассказывая что это такое и зачем ими нужно пользоваться).
- Если менеджера паролей нет, то мы спрашиваем у пользователя адрес эл. почты. Туда высылаем письмо с рекомендацией записать куда-то ключ, а письмо не удалять, а заархивировать (так как восстановления паролей у нас нет). Сервер никуда не сохраняет почту.
- Если есть менеджер паролей мы показываем ключ и предлагаем сохранить в него ключ (объясняя, что никакого востановления паролей у нас нет).
После этого, userId
и encryptionSecret
сохраняется в localStorage
,
а accessSecret
ставиться как HttpOnly
-кука (и больше н видна из JS).
userId
и accessSecret
сохраняются на сервере, но encyptionSecret
сервер никогда не знает.
Когда пользователь хочет войти в свой аккаунт на другом клиенте, он жмёт «Войти» и вводит свой ключ взяв его из менеджера паролей или найдя эл. письмо с регистрации.
Клиент подключается к серверу используя userId
и accessSecret
и загружает
зашифрованные данные, которые расшировывает локально используя
encyptionSecret
. Если надо сохранить что-то на сервер, то данные снова
шифруются и загружаются в облако.
Если пользователь забыл ключ, то ему предлагается два выхода:
- Поискать в почтовом клиенте письмо с ключом (используя особое слово, которое есть только в тексте письма с регистрации).
- Взять клиент, который уже залогинен, и восстановить ключ в нём.
Пользователь может опционально поставить отпечаток пальца
для доступа к
encryptionSecret
. Сервер скажетaccessSecret
только добавив факт восстановления в лог.
Однако, если пользователь удалил письмо и потерял все залогиненные клиенты, то данные будут потеряны. Мы предполагаем, что список подписок, не такая критическая информация и нормально её потерять, совершив несколько ошибок.
- Общий-для-всех-сайтов пароль пользователя утёк через взлом другого сайта. На наш метод эта атака не действует, так как мы генерируем ключ сами.
- Взломали наш сервер. На нашем сервере нет
encyptionSecret
, данные полностью анонимны и зашифрованы. - XSS-атака веб-клиента. У JS не будет доступа к
accessSecret
. - Перехват данных между клиентом и сервером. Данные не расшифровать
без
encyptionSecret
. - Взлом машины клиента. Тут мы можем надеятся только на изоляцию приложений в ОС, но полный ключ, скорее всего, можно будет восстановить.
- Устройство пользователя украдено. Пользователь через другой клиент может
сменить
accessSecret
иencryptionSecret
, сбросив доступ всех клиентов. - Член семьи получает доступ, пока пользователь спит. После восстановления ключ, клиент ещё пару дней показывает предупреждение, что ключ был восстановлен.
- Система непрывычная. Поэтому мы сначала даём попробовать приложение, чтобы человек шёл на сложную регистрацию уже понимая пользу от продукта.
- Сложно восстановить приложение в случае потери ключа. Пару способов мы даём, если пользователю не повезло, то в потеря подписок не критичная.
Какие ещё векторы атаки или проблемы в UX вы видете?
При такой схеме брокер нужен только для установки соединения, и, при желании, его можно хостить самому (надо сделать дешевую в хостинге serverless версию).