Безопасная авторизация в современных мобильных приложениях: миф или реальность?

Мы привыкли доверять приложениям, которые установили на свои гаджеты. Порой обоснованно, порой не очень. Если посмотреть документацию на API авторизации какого-нибудь крупного российского банка или соцсети, то можно увидеть Oauth 2.0, OIDC, authorization code flow и т.д. К сожалению, в большинстве случаев это либо не соответствует действительности вообще, либо частично. Как будто за всеми этим упускается один важный момент, и сегодня мы поговорим об этом более подробно.

Смотрим примеры

Пару лет назад я начал активно интересоваться вопросами авторизации и аутентификации — кроме изучения соответствующих опенсорсных решений, таких как keycloak, я присоединился к сообществу spring security и начал активно вносить свой вклад в развитие фрэймворка — мои активности можно посмотреть в аккаунте на github, там как мелкие доработки, так и полноценные core-фичи. По мере накопления опыта мой скептицизм в отношении безопасности некоторых приложений, установленных на моем iphone 12, только увеличивался. На самом деле все не совсем так — я пришел к выводу, что подавляющее большинство мобильных приложений в моем телефоне не очень-то и безопасны в плане авторизации. Давайте рассмотрим пару примеров. Вот с чего начинается процесс авторизации и аутентификации в приложении одного крупного банка (не вижу смысла скрывать его название):

2d0642a3adf0b8faccddd6061c560753.jpg

После ввода номера телефона приходит смс с кодом, который также надо ввести. Это первый фактор. Второй фактор можно пройти по номеру карты и паролю:

bda86c778a29f6f1849e0a71b03b627d.jpg

А вот так выглядит первый экран авторизации в одной известной отечественной соцсети:

c2228c9e692a4305ea892eaf08c37163.jpg

В общем-то точно такое же начало, как и в предыдущем случаем. Для сравнения давайте посмотрим с чего начинается авторизация во всеми нам известном сервисе от компании Google:

ee630ef5a7e000d16c73162f874b8670.jpg

Как минимум у нас появилась кнопка «Войти». Уже лучше, давайте нажмем эту кнопку.

59d57ec714c084bf2799986250788235.jpg

Youtube честно нас предупреждает, что для входа в приложение будет использован google.com. Хорошо, продолжим.

812b9b24ad3940ac3bc829936aea78cc.jpg

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

Посмотрим еще один пример авторизации от Microsoft:

c2ab2387bb35cc9d67067585a127cc85.jpg

Кнопка есть, как и в предыдущем варианте. Далее:

8f818776c169d02de24c724f76b7be4c.jpg

Уже знакомое нам предупреждение. Продолжаем:

86b7e9df9abf6ae03181f82b93be7ed7.jpg

Я думаю, что дальше нет смысла продолжать.

Разбор

Видно, что первые два варианта авторизации сильно отличаются от youtube и github по своей природе. Скорее всего большинство пользователей (и опытные it-инженеры, в том числе специалисты по безопасности) не увидят тут какого-либо подвоха и спокойно будут вводить свои авторизационные данные что в приложение вк, что в youtube. Проблема в том, что у первых двух приложений есть один важный момент, связанный с упомянутым выше Ouath 2.0 — они фундаментально небезопасны, т.к. их авторизация противоречит основной идее Oauth 2.0. А точнее — не отдавать клиентскому приложению свои учетные данные (логин, пароль). Мы видим, что youtube так не делает, вы не вводите в нативных формах приложения логин, пароль, какие-либо коды из смс, и т.д., youtube открывает для вас отдельное браузерное окно, где мы видим сервер авторизации google, и вот ему вы уже честно отдаете свой логин, пароль и все, что он у вас попросит. Аналогичная ситуация у github. Оба этих варианта подразумевают, что есть некий сервер авторизации, которому вы доверяете, на нем вы проходили регистрацию, и приложение всегда предупреждает вас, что именно этот сервер сейчас запросит у вас учетные данные. Безопасно получить доступ к этому серверу можно только через браузер, который должен открыться отдельно от самого приложения. У того же google процесс авторизации внешне выглядит одинаково, при этом неважно, где бы вы авторизовывались — где-то в браузере на своем ПК или в мобильном приложении. Что касается первых двух приложений, то все, что требует протокол авторизации вводится исключительно в самом приложении (не в отдельно открытом браузере). И тут важно понимать почему это небезопасно.

Вот что написано в RFC:

4ef711ed8df17e6ecb7c5eb259afb896.png

Наверное, кто-то скажет, что это ведь не password grant как таковой, но по факту разницы нет. Это ровным счетом тоже самое, более правильно было бы написать не про конкретный grant, а про возможность ввода каких-либо авторизационных данных на клиенте в принципе.

Про потенциальные утечки пароля, трояны, перехватывающие otp и т.д. мы уже слышали много раз. Да, такое возможно, история знает много примеров, когда учетные данные куда-то утекали из клиентского приложения. В принципе, я верю, что такое сейчас случается нечасто и в этом плане современные мобильные приложения можно считать относительно безопасными. Что конечно же является большой натяжкой. Не нужно сбрасывать со счетов этот момент, но прежде всего стоит обратить внимание на кое-что другое — вы привыкаете вводить свой логин и пароль в приложение, в его интерфейс, а не в браузер. Никто вас не предупреждает, что ваше приложение хочет использовать какой-либо сервер для авторизации. Вы просто верите, что вы вводите пароль туда, куда надо. Наученные годами пользования youtube пользователи могут несколько раз подумать прежде, чем вводить свой пароль куда-то в другое место, где не выскакивает окно предупреждения и не открывается привычная страница google.com со знакомыми кнопками. А могут и не думать вовсе, т.к. в телефоне есть куча приложений, где такого нет, а значит можно вводить свой логин пароль как угодно и куда угодно.

Удивительно, что такой проблемой страдают, наверное, все отечественные банки, где процесс авторизации идет исключительно в мобильном приложении. И как бы странно это не звучало, но на вопрос «неужели крупный банк может подвергать опасности меня и мои финансы?» ответ — да, может. Если посмотреть с какой периодичностью в том же app store появляются откровенно мошеннические приложения, которые пользуются, тем фактом, что пользователь просто не привык видеть то, что он видит при авторизации в том же youtube. Например, раз, два, три. Это классическая атака «человек посередине».

145ad47dbd05c70fc43805f624587672.png

Можно бесконечно предупреждать о фейковых приложениях в app store, пользователям от этого легче не станет, причины таких атак и, как следствие украденных учетных данных (и денег тоже) кроются в самих компаниях-разработчиках этих приложений — нужно предпринимать конкретные шаги для уменьшения вероятности атак, следуя рекомендациям rfc и хотя бы того же Oauth 2.0.

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

И что нам делать?

Увы, мы тут заложники ситуации. Пока в наших телефонах будут такие приложения мы будем вынуждены вводить свои учетные данных именно так, как они требуют. Неважно безопасно это или нет. Причин тому может быть много, я слышал разные объяснения — от классического «исторически так сложилось» до «бизнес требует».  Наверное, в первую очередь тут стоит работать с разработчиками приложений и специалистами по it-безопасности, чтобы у них в головах появились новые категории и паттерны веб-секьюрити. Может ли решить все проблемы массовое внедрение настоящего Oauth 2.0 в мобильных приложениях. Я думаю, что нет, проблемы все равно останутся, но мы можем решить часть этих проблем и уменьшить поверхность атак и вариантов мошенничества, а это уже будет небольшой победой.

Вместо послесловия

Где-то год назад на форуме keycloak появился вопрос Programmatically registering & authenticating passkeys. Автор пытался понять есть ли у keycloak какой-либо REST API для авторизации через пасскеи (т.е. без пароля).  На что получил весьма содержательный ответ от одного из основных разработчиков keycloak:

5da98950e9ab66238feb38dbe4141493.png

Тут добавить нечего…

© Habrahabr.ru