Comments 41
Приложение может нарисовать окно, похожее на окно браузера.
Увы, это факт. Поэтому при запросе авторизации приложение дает предупреждение о том, что будет использовано для авторизации, а в браузерном окне виден адрес сервера авторизации. Это не решит проблему в 10 из 10 случаев, но как минимум позволит уменьшить поверхность атаки для наиболее внимательных пользователей, особенно если они годами вводили логин и пароль именно таким способом.
Удивительно, что такой проблемой страдают, наверное, все отечественные банки, где процесс авторизации идет исключительно в мобильном приложении.
Погодите. С чего вы решили, что при входе в приложение банка я доверяю google.com, которому одновременно доверяет и банк? В приложение Сбер/Тиньков можно войти по кредам гугля? И давно ли?
В моем понимании, Сбер скажем использует Oauth не когда вы входите в Сбербанк Онлайн, а когда вы входите куда-то по СберID, т.е. именно сервис Сбера и является тем, кто аутентифицирует пользователя. Т.е. например, при входе по СберID в megamarket.ru, ну или там Купер и т.п. .
Погодите. С чего вы решили, что при входе в приложение банка я доверяю google.com, которому одновременно доверяет и банк? В приложение Сбер/Тиньков можно войти по кредам гугля? И давно ли?
В статье речь шла не про вход по кредам гугла в приложениях сбера или тинька, а про то, что вход в них должен осуществляться через отдельное браузерное окно как и предполагает Oauth 2.0.
В моем понимании, Сбер скажем использует Oauth не когда вы входите в Сбербанк Онлайн, а когда вы входите куда-то по СберID, т.е. именно сервис Сбера и является тем, кто аутентифицирует пользователя.
Даже если это и правда, то так делать, как Сбер, категорически неверно. В rfc вполне четко прописан процесс авторизации для мобильных приложений, а если компания так, как написано в стандарте делать не хочет, то она не только подвергает своих пользователей лишней опасности, но и учит их доверять учетные данные своему приложению, а не серверу авторизации (тому же СберID или "Сбер Онлайн", неважно), что в общем-то прямо и сказано в спецификации. Отсюда и результат. Особенно интересно читать отзывы в app store от тысяч пользователей, которые установили себе эти приложения и чьи учетные данные угнали.
@sshikov имеет в виду, что делегирование аутентификации/авторизации не нужно для first-party клиента - OAuth/OpenID придумали для third-party клиентов. Приложение VK это first-party клиент по отношению, поэтому там достаточно эндпойнта с логин-паролем (и 2FA), так что нет смысла делегировать аутентификацию самому себе. YouTube делегирует аутентификацию Гуглу, скорее всего, потому что это банально разные организации и домены. А github кмк просто какую-то фигню сделали
@sshikov имеет в виду, что делегирование аутентификации/авторизации не нужно для first-party клиента - OAuth/OpenID придумали для third-party клиентов
Это неверное утверждение. First patry application - это приложение, созданное разработчиком самой платформы, например, предустановленные приложения для ios, разработчик которых apple. Для таких приложение есть особая авторизация, которая пока еще в драфте. В таких приложениях риски всегда ниже, поэтому стандартные процессы Oauth 2.0 во многом бессмысленны. Что сбер, что вк разработали не google и не apple, и они уж точно не предустановлены ни в одну из ОС.
Я неверно выразился - на самом деле мобильное приложение ВК (если бы это был flow OAuth) было бы User Agent, а не клиентом. Клиент это сам сервер авторизации ВК, поэтому делегирование тут бессмысленно - сервер ВК не станет же просить доступа у себя самого
Я неверно выразился - на самом деле мобильное приложение ВК (если бы это был flow OAuth) было бы User Agent, а не клиентом. Клиент это сам сервер авторизации ВК, поэтому делегирование тут бессмысленно - сервер ВК не станет же просить доступа у себя самого
Извините, но это тоже неверные утверждения, либо я не понимаю что вы имеете в виду. В спецификациях четко прописаны роли в oauth 2.0, но если кто-то их как то иначе интерпретирует, то это явно не проблема стандарта. Сервер авторизации это не клиент, а скаченное из app store приложение должно авторизовываться на сервере, через его web интерфейс.

Это приложение подходит под ваше определение? Ему можно доверять? Как оно будет вас авторизовывать? И это app store, 4,5 звезды.
Даже если это и правда, то так делать, как Сбер, категорически неверно.
Вы предлагаете отдельное окно, и считаете это критически важным? Ну ок, допустим - только я не улавливаю, почему пользователь, который не может отличить фейковое приложение банка от настоящего не перепутает точно так же фейковое окно браузера с настоящим?
P.S. По сути, вот ниже уже сформулировали мой вопрос иными словами:
если мы не доверяем приложению, то почему мы должны доверять контенту "браузерного окна", которое оно открывает?
Ну т.е. исходные данные для меня простые - я доверяю своему банку деньги. И я доверяю его приложению (хотя разумеется, допускаю, что там могут быть баги). И когда я ставлю это приложение, я убеждаюсь дважды, что оно настоящее. В противном же случая я не вижу разницы. Если вы видите - поясните, в чем она?
Вы предлагаете отдельное окно, и считаете это критически важным?
Это не я предлагаю и считаю это критически важным, это предлагает rfc и ouath 2.0 в целом (и считает не просто критически важным, а основной идеей всего фрэймворка).
Ну т.е. исходные данные для меня простые - я доверяю своему банку деньги. И я доверяю его приложению (хотя разумеется, допускаю, что там могут быть баги). И когда я ставлю это приложение, я убеждаюсь дважды, что оно настоящее. В противном же случая я не вижу разницы. Если вы видите - поясните, в чем она?
К сожалению это то, к чему мы пришли на данный момент. С точки зрения rfc и oauth 2.0 в целом доверять нужно серверу авторизации, чью страницу для ввода логина и пароля мы видим в браузере. Точка. Можно с этим спорить, но это факт. На этой идее основаны современные мобильные sdk, так работает keycloak, и не просто так мэйнтейнеры того же keycloak нас предупреждают:
Secure authentication is always about doing the proper things on the secure server, aka Keycloak, with the use of the users browser. Please, do yourself and your users a favor and read and understand the specs, before implementing “something that just somehow” works.
Безопасная аутентификация всегда предполагает выполнение правильных действий на защищенном сервере, известном как Keycloak, с использованием браузера пользователя. Пожалуйста, сделайте себе и своим пользователям одолжение: прочитайте и поймите спецификации, прежде чем внедрять «что-то, что каким-то образом» работает.
Еще раз цитата из rfc:
The resource owner password credentials grant [RFC6749] MUST NOT be used. This grant type insecurely exposes the credentials of the resource owner to the client. Even if the client is benign, this results in an increased attack surface (credentials can leak in more places than just the authorization server) and users are trained to enter their credentials in places other than the authorization server.
Даже если клиент безопасен, это приводит к увеличению поверхности атаки (учетные данные могут просачиваться не только на сервер авторизации), а пользователей обучают вводить свои учетные данные не только на сервере авторизации.
Я понял, о чем вы. Практически согласен, кроме одного - вы говорите о стандарте, который не предназначен для first party apps. А стандарт для них - в драфте. И мне лично не очевидно, почему применение стандарта для приложений, к которым он (условно) не подходит, лучше в принципе, чем отступление от него. Да, отступление - это риски (которые надо анализировать конкретно). Да, это учит пользователей нехорошему - согласен.
В first party apps все немного по-другому, там могут быть утечки пароля или логина с последующим перехватом их трояном например. Все, что мы ставим себе из сторов это не first party apps и там лучше следовать рекомендациям rfc. Грубо говоря, камере на айфоне это не нужно,т.к. это first party app, а вот сберу из app store не помешало бы, т.к. это third party app.
Вот не очевидно. СберИд это тоже платформа, и если посмотреть в предлагаемый вами стандарт, то там написано так:
This specification MUST only be used by first-party applications, which is when the authorization server and application are operated by the same entity and the user understands them both as the same entity.
Т.е. сервер авторизации и приложение управляются Сбером? Значит Сбербанк Онлайн это first-party application, почему нет-то? Тут про ОС и предустановку ничего не написано (хотя ваши мысли что тут риска меньше, я вполне понимаю).
First party application это, то что идет в комплекте с вашим девайсом. Если у вас iphone, то все, что там установлено по умолчанию это и есть first party application - safari, заметки и т.д. Для таких приложений сейчас принимаются попытки написать стандарт, цитату из которого вы привели. Приложение сбера или вк были бы first party application если бы его разработчиком был apple. Поэтому для вашего девайса (iphone например) это самые что ни на есть third party app и всегда есть отличный от нуля шанс скачать из app store что-то не то под видом сбера или вк. И ввести туда логин и пароль (который очень часто одинаковый везде, где только можно). Тут не идет речи о том, чтобы полностью решить эту проблему, это невозможно, но хотя бы сократить поверхность атак - если 40% пользователей обратят внимание, на то, что страница в браузере не та, то это уже хорошо.
Ну в том стандарте ничего не написано про то, что приложение идет в комплекте. Я вам же точную цитату привел - авторы стандарта считают таковыми приложения, где сервер авторизации и приложение - единое целое. И "user understands them both as the same entity". Ну т.е. тут подчеркивается, что юзер должен понимать, что это одна компания.
В то же время там написано вот что:
Because this specification enables a client application to interact directly with the end user, and the application handles sending any information collected from the user to the authorization server, it is expected to be used only for first-party applications when the authorization server also has a high degree of trust of the client.
This specification is not prescriptive on how the Authorization Server establishes it's trust in the first-partyness of the application. For mobile platforms, most support some mechanism for application attestation that can be used to identify the entity that created/signed/uploaded the app to the app store. App attestation can be combined with other mechanisms like Dynamic Client Registration [RFC7591] to enable strong client authentication in addition to client verification (first-partyness). The exact steps required are out of scope for this specification. Note that applications running inside a browser (e.g. Single Page Apps) context it is much more difficult to verify the first-partyness of the client. Please see Section 9.8 for additional details.
То есть в спецификации подразумевается, что между клиентов (приложением) и сервером авторизации есть некоторая степень доверия, а уже как она была достигнута, в спецификации не уточняется. Сказано лишь, что "есть какие-то способы это сделать в современных мобильных приложениях". Мы уже видели эти способы, как оно работает на самом деле и можно ли доверять на 100% сторам.
И тут же идут пункты 9.2 и 9.3, где прямым текстом говорится, что это не очень то и безопасно:
There are two ways using this specification increases the risk of phishing.
With this specification, the client interacts directly with the end user, collecting information provided by the user and sending it to the authorization server. If an attacker impersonates the client and successfully tricks a user into using it, they may not realize they are giving their credentials to the malicious application.
In a traditional OAuth deployment using the redirect-based authorization code flow, the user will only ever enter their credentials at the authorization server, and it is straightforward to explain to avoid entering credentials in other "fake" websites. By introducing a new place the user is expected to enter their credentials using this specification, it is more complicated to teach users how to recognize other fake login prompts that might be attempting to steal their credentials.
Благодаря этой спецификации клиент напрямую взаимодействует с конечным пользователем, собирая предоставленную пользователем информацию и отправляя ее на сервер авторизации. Если злоумышленник выдает себя за клиента и успешно обманом заставляет пользователя использовать его, он может не осознавать, что передает свои учетные данные вредоносному приложению.
Не стоит забывать, что пока что это драфт, т.е. эта версия стандарта еще не принята, что неудивительно, т.к. вопросов очень много. В любом случае ни одно из существующих, например, в app store приложений не может эту спецификацию реализовывать, т.к. ее еще банально нет. И как будто бы, из того, что я вижу она провисит в драфте не один год, пока не будет придуман тот самый механизм "app attestation", чтобы можно было устанавливать доверительные отношения между клиентом и сервером, но слабо себе представляю что это будет за механизм. Поэтому сейчас ничего лучше OAuth 2.0 for Native Apps сейчас нет, по крайней мере так считают эксперты мирового уровня.
If an attacker impersonates the client and successfully tricks a user into using it, they may not realize they are giving their credentials to the malicious application.
Если клиент-приложение злоумышленника выдает себя за правильного клиента - то он в процессе входа отправляет пользователя на какой-то левый сервер аутентификации, где пользователь вводит креды и... далее они успешно утекают. Чего и пытались избежать.
Т.е. мы заменяем задачу определения "а то ли злодейское ли это приложение, туда можно креды вводить?" на задачу "а злодейский ли этот сервер, туда можно креды вводить?"
Ну так себе замена. В случае сервиса без всякой "экосистемы", который только сам себя обслуживает и учетки свои собственные ведет (не технически, а с точки зрения пользователя) - получается только лишнее усложнение.
Авторы спецификации подразумевали, что first party app по умолчанию обладает большим уровнем доверия. Как его достичь не уточняется, но это может быть, например, внутреннее приложение компании (для какой-нибудь курьерской службы, например), по сути это и есть first party app - предустановленный софт либо внутренние разработки не для массового сегмента. Вот что говорит microsoft по этому поводу на своем форуме.
В целом, я согласен, что при прочих равных условиях это небезопасно и противоречит оригинальной идее oauth 2.0
Что мешает в фейковом приложении нарисовать аутентификацию в браузере и нарисовать любой нужный адрес? Фактически мы скрываем строку адреса и в фейковой строке адреса пишем что угодно хоть гугл хоть гуглосбер. При этом смысл приложения как раз в том, что мы не авторизуемся постоянно, а чуть ли не один раз на всю жизнь, и уже спустя неделю вы не вспомните как выглядел процесс авторизации и уж точно не будете помнить адрес сервера авторизации. Если брать гугл у него много разного добра и там часто можно столкнуться с авторизацией, в сбере не так часто, а условный тинек, где вы будете авторизовываться помимо самого тинька?
Кстати СберID это не платформа как таковая, а сервер авторизации. Мне кажется, что это очень сильно кастомизированная keycloak., но могу ошибаться.
Почему вход в приложение банка – это OAuth? Вы входите в банк с логином и паролем банка, а не с токеном со стороннего сервера аутентикации.
"Не называйте мне никаких кодов. Сейчас я переключу вас на робота и вы продиктуете код ему". Просто вспомнилось, извините.
Я честно говоря не понял идею - если мы не доверяем приложению, то почему мы должны доверять контенту "браузерного окна", которое оно открывает?
Эта идея - суть есть краеугольный камень всего oauth 2.0 (и не только). Ее можно критиковать (в некоторых аспектах вполне обоснованно), но реальность такова, что конкурентоспособной альтернативы предложено не было. И, к сожалению, эта идея почему-то вызывает у людей отторжение, видимо годами привыкшие вводить свои данные в нативные компоненты приложения, пользователи начали считать это нормой.
Вы упускаете момент, что OAuth разрабатывался для браузеров, где действительно приложение не может залезть в соседнюю вкладку и посмотреть креды, поэтому принцип «не давать креды напрямую приложению» работает. В случае нативных приложений это не работает, потому что оно фактически имеет полный доступ к любым WebView, которое оно открывает, и в этом разделении нет смысла.
Да и, как вам уже написали выше, нет никакого смысла не доверять пароль от Тинькофф их же приложению. Вы предлагаете забить на здравый смысл и следовать стандарту ради следования стандарту.
Вы упускаете момент, что OAuth разрабатывался для браузеров, где действительно приложение не может залезть в соседнюю вкладку и посмотреть креды, поэтому принцип «не давать креды напрямую приложению» работает. В случае нативных приложений это не работает, потому что оно фактически имеет полный доступ к любым WebView, которое оно открывает, и в этом разделении нет смысла.
Возможно, вместе со мной все это упускают разработчики AppAuth, google, сообщество spring security, keycloak и все, кто разрабатывал этот стандарт. Такое вполне возможно, но я не думаю что это так. Скорее что-то упускают разработчики мобильных приложений, которые делают свои системы безопасности как-то иначе. Вам так не кажется?
(Глядя на таймлайн, который долго тянется и начался как-то поздно) есть подозрение, что это связано с желанием влезть куда надо и куда не надо. Объяснение "безопаснее, когда приложение не видит кредов" возможно, верное. Но тогда надо не здоровенным браузером с огромной поверхностью атаки пользоваться, а придумать стандартный системный диалог/системное приложение, который и предназначен для общения с сервером аутентификации.
Где всяких JS, html и прочего, что злодей может как-то изменить, просто нет, а есть строгий захардкоженный протокол того, что должно происходить.
Простите, а аргументы будут у вас? Апелляция к авторитетам в виде гугла и прочих громких имен аргументом не является.
Минуточку. А почему вы решили, что это аргументы? Вы считаете, что я поставил себе цель доказать кому-то, что стандарты безопасности и построенные на их основе технологии и фрэймворки не являются полной ерундой? И затеял спор на эту тему? Извините, но это не так, со стороны это выглядит как абсурд. Есть набор фактов - есть спецификация, есть описание конкретной реализации в стандарте, есть keycloak, spring authorization server, okkta, auth0, которые реализовывают эти стандарты и рекомендуют использовать их именно так, как реализовано. В конце концов есть фрэймворки, которые поддерживают именно такие подходы. Пруфы можно приводить до бесконечности. И это все факты. Что тут для кого авторитет, а для кого нет, тут пусть каждый сам решает. Моя цель, как разработчика одного из таких фрэймворков, указать на все эти факты. А что с этим делать - решайте сами.
Так так так, браузер получает и отправляет сетевые запросы для авторизации и получения токена сессии, приложение делает то же самое, но не рендерит html+css. В чём разница получается? В том, что не видим, на какой домен мы отправляем данные? Ну я лично не думаю что Тинькофф украдёт мой номер телефона и код для входа в тинькоффк.
Если же речь про зловреды и mitm, то с браузером ведь точно такая же история, а если говорить про уязвимости памяти, то достать введённые данные из нативных компонентов скорее всего сложнее, чем из формочки в браузере, разве нет?
И в чём проблема для фейковых приложений открыть страничку в браузере и просто получить токен сессии??? Это наоборот более уязвимая и простая для мошенников стратегия: пользователь увидит что домен настоящий и откинет сомнения, не надо пытаться повторить формы авторизации, все двухфакторки пользователь подтвердит сам, а зловред получит готовенький токен.
Когда же авторизация происходит в нативном клиенте, то у разработчиков есть отличные возможности для обнаружения поддельных запросов и подробностей о версии клиента, что усложняет процесс мошенникам.
Я понимаю, что это фундаментальный принцип какой-то там, придуманный кем-то там, но я не вижу особых причин для критики или сомнений в надёжности тех сервисов, которые его не придерживаются. Может я чего-то не понимаю?
Так так так, браузер получает и отправляет сетевые запросы для авторизации и получения токена сессии, приложение делает то же самое, но не рендерит html+css. В чём разница получается? В том, что не видим, на какой домен мы отправляем данные? Ну я лично не думаю что Тинькофф украдёт мой номер телефона и код для входа в тинькоффк.
Тинькофф точно не украдет ваш номер телефона, по крайней мере мы хотим в этой верить)) А вот оно украдет. И как понять, что вы ввели логин пароль не в приложение т-банка а вот сюда? Окно браузера с всплывающим предупреждением дает хоть какой-то шанс на, что пользователь обратит внимание на то, куда он вводит логин и пароль. Особенно если он это делал годами и другого варианта у него нет.
И в чём проблема для фейковых приложений открыть страничку в браузере и просто получить токен сессии??? Это наоборот более уязвимая и простая для мошенников стратегия: пользователь увидит что домен настоящий и откинет сомнения, не надо пытаться повторить формы авторизации, все двухфакторки пользователь подтвердит сам, а зловред получит готовенький токен.
В момент редиректа зловредное приложение и правда может перехватить любые данные. Для этого был придуман Proof Key for Code Exchange by OAuth Public Clients - использование code_verifier
иcode_challenge
. Кроме того, если использовать universal links или applink, то такая атака в принципе не сработает.
В момент редиректа зловредное приложение и правда может перехватить любые данные.
Почему перехватить? Оно честно, точно так же как родное приложение банка делает, запросит токен доступа. И получит его. У сервера авторизации по большому счету нет же способа проверить, кто к нему стучится. Родное приложение или его слегка модифицированная злодеем версия.
Как минимум зловреду нужно знать client_id,
а даже если он его получит, то ему все также надо пройти authorization code flow.
Злоумышленник может создать приложение, которое перехватывает такие же редиректы, как у нашего приложение. Но с Proof Key for Code Exchange by OAuth Public Clients эта проблема решается.
Идея использовать браузер для бозопасного доступа к доверенному серверу основана на том что сам браузер является доверенным, но пользователь может использовать любой браузер, в том числе и угоняющий его пароли из форм ввода, возможно не осознавая этого. Как рассмотренная техника может помочь в данном случае?
Смотрим документацию на ASWebAuthenticationSession
от Apple:
Use an
ASWebAuthenticationSession
instance to authenticate a user through a web service, including one run by a third party. Initialize the session with a URL that points to the authentication webpage. When the user starts the authentication session, the operating system shows a modal view telling them which domain the app is authenticating with and asking whether to proceed. If the user proceeds with the authentication attempt, a browser loads and displays the page, from which the user can authenticate. In iOS, the browser is a secure, embedded web view. In macOS, the system opens the user’s default browser if it supports web authentication sessions, or Safari otherwise.
Выделю отдельно: "In iOS, the browser is a secure, embedded web view". Для полного понимания также рекомендую ознакомиться с AppAuth, для андроида также имеется. На данный момент критических уязвимостей в этих вариантах авторизации не выявлено, в конце концов разработчики стандартов авторизации не настолько дилетанта, чтобы оставить такую гору проблем в своих решениях, можете мне поверить.
Я не пользователь ios, где все браузеры это все равно сафари, возможно там в браузере есть элемент безопасности. Но на android или desktop платформах откроется любой браузер который пользователь считает основным. И безопасный он или нет решает пользователь доверяя ему. Так что он также может ошибиться и поставить левый браузер вместо левого приложения ЦветногоБанка.
Вы уверены, что это будет работать в AppAuth именно так? В документации написано:
The library follows the best practices set out in RFC 8252 - OAuth 2.0 for Native Apps, including using Custom Tabs for authorization requests. For this reason,
WebView
is explicitly not supported due to usability and security reasons.
Т.е. будет использованы custom tabs и это не то, о чем говорите вы. Или я ошибаюсь? Можете пояснить?
Да Custom tabs это просто современный способ взаимодействия с браузером, что-то среднее между тем чтобы открыть webview в приложении, и полным переходом в приложение браузера, технически откроется процесс браузера, но его окно будет внешне уразаным и будет выглядеть как часть текущего приложения. Этот протокол реализуется всеми браузерами современными на android. Каким браузером пользователь пользуется по умолчанию тот и откроется..
Спасибо, я понял о чем вы.
Этот протокол реализуется всеми браузерами современными на android
Нет, не всеми. Только браузерами на основе chromium. Кроме того для того, чтобы полноценно работал AppAuth (т.е. флоу авторизации oauth 2.0) в браузере необходима поддержка app-links. В свое время был вопрос на stackoverflow почему AppAuth не работает в Opera, Dophin, Firefox и т.д. Ответ дал сам лид AppAuth. То, о чем говорите вы, в теории реально - необходим зловредный браузер на основе chromium, который поддерживает custom tabs и app-links, этот браузер должен попасть в ось пользователя, а тот уже должен начать авторизовываться в нем. Насколько это реально? Дума, что реально. Является ли это критической уязвимостью, из-за которой нужно отказываться от oauth 2.0? Думаю нет. Известно, что 65% рынка это chrome (включая ios), что делает авторизацию в таких девайсах относительно безопасной. В любом случае - фишинг через откровенно мошеннические приложения, где пользователь вводит свои креды в никуда, (таких приложений в том же app store полно: сбер, т-банк, висят они там долго, не удаляются), в последнее время стал массовой проблемой, один telegram чего стоит.
Безопасная авторизация в современных мобильных приложениях: миф или реальность?