Pull to refresh

Comments 30

Этак мы до кербероса доберёмся. kinit — получил токены — поехали.
Если твой API предоставляет возможность сделать что-то нежелательное от имени пользователя, то это проблема кривого API, а не авторизации OAuth.

То есть АПИ соцсети не должен позволять написать пост от имени пользователя?

Вы меня не поняли. Объясню по-другому.

Вы пишете, что «сторонние приложения могут подключиться к API и от имени пользователя что-то сделать».

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

Я? Я этого не пишу.


Потому что при правильном API сервису без разницы, какое именно приложение используется пользователь — «родное», «стороннее» или вообще самописное.

Технически — без разницы. Но практически разница есть: если вернуться к примеру соцсетей, то про "родное" приложение точно известно, что оно постит именно то, что просил пользователь. А неизвестное стороннее — может постить что угодно, и тем самым совершать то самое "нежелательное", от которого и соцсети, и пользователю хотелось бы защититься.

Это проблема пользователя, что он ставит такие приложения, а не OAuth. Обвинять в этом OAuth — всё равно, что обвинять протокол HTTP в том, что через него взламывают сайты.

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

1. На мобильном в интернеты не выхожу.
2. На мобильном в интернетах сидят в основном люди, которым нечем себя занять.
Минусовали сидящие с мобилочек? :)
Либо я вас не понял, либо вы перегнули палку.
client_id и client_secret — это, фактически, имя и пароль для авторизации.
То есть ваш вопрос звучит «как нам узнать, что именем и паролем пользователя не завладел злоумышленник?».
Общий ответ — никак. Можно придумать двухшаговую авторизацию (по двум независимым каналам; можно десятишаговую, по десяти разным каналам) и немедленно проиграть в удобстве пользования.
А можно сказать «пользователь сам охраняет свои данные».
Или я вас понял неверно?

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

Разумное замечание. Но это только одна из освещаемых проблем.

Насколько я понимаю, OAuth как раз и создавался «безопасным» в частности в том смысле, что завладеть вашим паролем (client_secret) было невозможно, если клиентом являлось серверное приложение (что на сколько я понимаю, отражено в OAuth 1.0 и в OAuth 2.0 Authorization code flow). Затем появилась необходимость использования не только серверных клиентов, где безопасность client_secret не может быть гарантирована (OAuth 2.0 Implicit flow). Но стандарт не дает никаких рекомендаций о том, как мы можем гарантировать, что клиент действительно серверный и соответственно, что мы можем ему позволить обращаться к какому-то чувствительному в этом смысле API.

Так же, некоторые популярные библиотеки, реализующие OAuth провайдер вообще не уделяют внимания необходимости разделения таких клиентов, например FOS OAuthServerBundle. Можно сказать, что направление пользователя по правильному пути это не задача библиотеки, но например django-oauth-toolkit делает на этом явный акцент.
Так всё очень просто. Если у вас один логин/пароль выдаёт доступ к нескольким серверам, то нельзя его вводить ни на каком из этих сервисов. Нужно проверенное стороннее приложение для получения токенов. А OAuth позволяет встроить ввод логина/пароля в одно из этих приложений, что плохо.

Если у вас логин/пароль для каждого сервиса разный, то эта тонкость не важна — если ты доверяешь сервису, значит ничего не потеряешь, доверяя его клиенту.

Кстати а кто нибудь знает когда авторизация через Твиттер перейдет на oauth2?

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

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

… а если у вас пользователь не регистрируется с устройства?

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

А браузер, чтобы зарегистрироваться через веб, он где запускает? :) А если у нас одно устройство уже зарегистрировано, на втором регистрация (или просто временная работа, в зависимости от ситуации) может идти с подтверждением через первое.

Есть, конечно, сценарий «регистрируемся через браузер на заведомо недоверенном устройстве» (публичный компьютер, скажем), но тут я вообще не вижу каких-то способов безопасной регистрации.
А браузер, чтобы зарегистрироваться через веб, он где запускает?

Где угодно.


А если у нас одно устройство уже зарегистрировано, на втором регистрация (или просто временная работа, в зависимости от ситуации) может идти с подтверждением через первое.

Подтверждением чего? Пользователя? Так это не то, что нам надо, нам надо знать, что клиентское приложение доверенное.

Где угодно.

Это "где угодно" в контексте обсуждения является устройством. :)


нам надо знать, что клиентское приложение доверенное

Не понял. Доверенное в каком смысле, что на сторону данные не сливает? Если клиентское приложение выпускает сам поставщик сервиса (или контролирует тех, кто их пишет), то он, очевидно, знает, доверенное оно или нет. Если же поставщик сервиса просто предоставляет API, под которое кто угодно пишет приложения, и никак эти приложения не контролирует, то очевидно, что вопрос доверия приложению ложится целиком на пользователя — либо верим издателю, либо нет. Разве есть ещё варианты?

Это "где угодно" в контексте обсуждения является устройством

Почему это вдруг?


Если клиентское приложение выпускает сам поставщик сервиса (или контролирует тех, кто их пишет), то он, очевидно, знает, доверенное оно или нет.

… и как нам определить, что к нам обратилось именно то приложение, которое мы выпустили?


вопрос доверия приложению ложится целиком на пользователя — либо верим издателю, либо нет. Разве есть ещё варианты?

Вот это и обсуждается в статье. И пока что вариантов особо нет, что и плохо.

Почему это вдруг?

Потому что браузеру надо на чем-то исполняться.


С приложениями я наконец понял, о чем вы, просто это немного вне контекста моего исходного комментария о сертификатах. :) Если клиент у нас ходит из неконтролируемой среды, то в целом по барабану, делается ли аутентификация по сертификату или чему-то ещё, проблемы будут схожие.

С приложениями я наконец понял, о чем вы, просто это немного вне контекста моего исходного комментария о сертификатах.

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

Эмм… это ведь именно в статье сертификаты преподносятся как решение для сред с ограниченным кругом пользователей, а я наоборот сразу написал, а потом и ещё и уточнил , что, хотя использовать их можно их где угодно, вопрос защиты в неконтролируемой среде они никак не решают. Ладно, раз мы теперь во всем согласны, замнем для ясности. :))

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

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

А если говорить о генерации чего-либо во время регистрации, то можно просто генерировать client_id и client_secret, но это, к сожалению, не решает описанных в статье проблем.

PKI тут не нужна и даже совершенно лишняя. Клиент привязан к конкретному сертификату, что именно нам нужно проверять у третьей стороны? Технически это то же самое, что аутентификация в SSH по ключам, например.


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

Sign up to leave a comment.

Articles