oauth redirect uri сбербанк
Токен OAUTH
Его использует большинство API.
Используйте OAITH-токен, если не требуется доступ к клиентским данным и не требуется согласие клиента на получение его данных.
Описание атрибутов запроса
Необходимо передать закодированные в BASE64 значения client id и client secret разделенные двоеточием в виде: «Ваsic» + пробел + :
Уникальный идентификатор запроса. Формируется по паттерну=(9|[a-f]|[A-F])<32>)».
Параметр необходим для журналирования входящих вызовов и удобства разбора инцидентов.
Чтобы обеспечить уникальность, можно использовать стандартные библиотеки и классы для генерации UUID/GUID (https://ru.wikipedia.org/wiki/UUID), убрав из результата разделители «-».
Принимает значение «application/x-www-form-urlencoded»
Принимает значение «application/json»
Идентификатор, полученный в личном кабинете на Портале после регистрации приложения.
Способ получения доступа (тип разрешения). Для данного взаимодействия необходимо использовать значение client_credentials.
Область видимости (scope), которая предоставляется клиентскому приложению. Необходимо передать значение, разрешенной области видимости.
Описание атрибутов ответа
Сгенерированный Access token.
Тип запрашиваемого токена. Всегда передается значение «Bearer».
Время в секундах, в течение которого действует Access Token.
Список групп персональных данных, на получение которых выдан данный токен. В список так же по умолчанию включается название сервиса API
Под каждый выпущенный токен создается сессия. Ее идентификатор передается в токене.
Пример ответа в случае ошибки
Типы возвращаемых ошибок
В заголовке запроса параметр Authorization имеет пустое значение или отсутствует.
В заголовке запроса некорректно указан параметр RqUID.
Корректный паттерн: «pattern»: «^((1|[a-f]|[A-F])<32>)$
В заголовке запроса параметр RqUID имеет пустое значение или отсутствует.
В теле запроса ошибка в параметре scope: используется пустое либо некорректное значение параметра.
Корректное значение параметра scope необходимо смотреть в документации к API.
В заголовке запроса указаны некорректные значения параметров accept или content-type.
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.
В теле запроса ошибка в параметре grant_type: используется пустое либо некорректное значение параметра.
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.
В теле запроса отсутствует параметр grant_type.
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.
В теле запроса параметры grant_type или scope содержат спецсимволы #*!$@%^&*()_+=-‘».
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.
1. client_id приложения, указанный в заголовке запроса «x-ibm-client-id», не зарегистрирован на Портале: приложение может быть удалено либо содержать синтаксическую ошибку.
2. в заголовке Authorization передается client_id, не соответствующий client_id приложения, с которым осуществляется вызов
Проверить параметры своего приложения можно через личный кабинет на Портале разработчика, в разделе «Приложения».
Значение client_id отсутствует в заголовке запроса в поле «x-ibm-client-id».
Ошибка в значениях параметров заголовка x-ibm-client_id или x-ibm-client_secret.
Проверить параметры своего приложения можно через личный кабинет на Портале разработчика, в разделе «Приложения».
Причинами ошибки могут быть:
Как правильно формировать параметр заголовка Authorization можно посмотреть в Параметрах запроса выше.
Проверить client_id и client_secret своего приложения на корректность можно через личный кабинет на Портале разработчика, в разделе «Приложения».
Причинами ошибки могут быть:
Проверить client_id и client_secret своего приложения на корректность можно через личный кабинет на Портале разработчика, в разделе «Приложения».
Приложение не авторизовано получать токен по указанному scope. Причинами могут быть:
Доступ запрещен. Для разбора данной ошибки необходимо обратиться в поддержку Банка.
Безопасность OAuth2
Данная блогозапись на хабр прежде всего обусловлена появлением «Ключницы» — хороший повод связать и перевести накопленное.
У нас в программе: вольный пересказ спек OAuth2, слабые стороны и Threat Model, 0day на хабретрюк с аутенфикацией.
OAuth2 это просто
Длинный, но правильный путь изучить его.
Для ленивых я опишу своими словами Authorization Code Flow как самый распространенный и безопасный, aka Server-Side.
Ключевые понятия — Клиент(website/online game/app), Юзер(you), Провайдер(facebook/vkontakte/google), Код(code) и Токен(access_token).
Клиент посылает Юзера — «авторизуй меня для доступа к твоим ресурсам». Юзер идет по ссылке к провайдеру, смотрит что от него требуют — scope параметр — жмет Разрешить. Далее Провайдер редиректит его назад на указанный redirect_uri на домене Клиента со следующими параметрами:
code — идентификатор Юзера у Провайдера, который нужен Клиенту чтобы получить Токен
state — то же значение что было передано на начальный URL. используется для защиты от CSRF и для удобства.
Код из себя не представляет никакой ценности для Юзера(и User-Agent соответственно) т.к. с его помощью нельзя совершать запросы API и нужен он лишь для одной цели — получения Токена.
Для получения Токена Клиент производит запрос на определенный эндпоинт, передав client_id, client_secret, code, redirect_uri по которому был получен код — таким образом Провайдер уверен что это нужный Клиент и по Коду он отдает Токен того самого Юзера. Как видите ни Юзер, ни User-Agent и клиентские скрипты не увидили настоящий Токен. Его знают только Клиент и Провайдер — в идеале.
Дальше Токен используют для совершения API запросов, впоследствии его можно рефрешить (для этого вместе с Токеном возвращается refresh_token).
Threat Model или Я Знаю О Чем Вы Подумали
1. А что если я подставлю такой redirect_uri который будет вести на свой сайт а потом использую этот Код сам для аутенфикации?
Все redirect_uri должны находится на домене Клиента. Часто разрешен еще домен Провайдера. Ваша ссылка вернет redirect_uri_mismatch.
2. ОК а что если я найду такое место на сайте Клиента, которое сольет мне Код? Может открытый редирект вида site.com?url=http://outsite.com или hot-linked картинку которая сольет реферер?
Каждый Код привязан к тому redirect_uri для которого он был выпущен и для получения Токена Клиент передает «правильный» redirect_uri. Если ваш Код был выпущен для clientsite.com/leak_referer а Клиент при получении Токена отошлет clientsite.com/facebook_callback то Провайдер не отдаст Токен.
3. А можно ли как то слить Код передав правильный redirect_uri?
Нет, т.к. любая правильная реализация Клиента обязана сразу редиректить на другую страницу после получения Кода — так что Код не виден даже в истории браузера.
Даже если вам удалось достать код для правильного redirect_uri то т.к. он уже был 1 раз использован он больше не активен.
4. Допустим у меня есть Код для моего аккаунта в соц сети выпущенный для правильного redirect_uri. Что будет если я заставлю посетить эту ссылку Васю?
В таком случае сайт Клиента подумает что ваш аккаунт в соц сети принадлежит Васе. И присоеденит его. Чтобы типичного CSRF не происходило Клиент обязан сохранять рандомное значение state в сессии/куке и проверять по возврату на колбэк на соответствие. Хотя, так почти никто не делает (точнее не делали).
Реальность
FB Reply Attack
Hijacking Account
Самая частая уязвимость, присутствует например на хабре — об этом ниже. Нарушается пункт 4.
Если вы видите в запросе state не спешите сдаваться. Что хабр, что digg.com не видели разницы между a12b6467c3fb385e237109502277ab26 и heyman0day123123
VK redirect_uri
Если вы используете Implicit Flow — т.е. получаете access_token от юзера напрямую, то нет никаких гарантий что этот токен принадлежит текущему юзеру. Он мог его просто украсть через вредоносного Клиента, и использовать чтобы попасть в аккаунт какого-то юзера на вашем сайте.
Обязательно проверяйте, был ли выпущен данный токен для вашего client_id.
Так же OAuth2 не дает никаких гарантий что пользователь дал вам те разрешения что вы запросили на этапе авторизации в параметре scope. Он мог просто удалить их — в итоге вы должны на колбэке проверить разрешил ли он что вы запросили.
Если на сайте найдена XSS то есть легкий способ украсть кучу access_token-ов. Возьмите authorize URL который сайт использует для facebook и замените response_type=code на token. Осталось вставить этот URL во фрейм, дождаться возврата токена в ссылке вида callback#access_token=123, срезать токен и слить его. Спамьте на здоровье!
0day на хабре?
Тот же эксплоит работает и для facebook/google только сложнее получить redirect_uri с кодом без использования его — нужен NoRedirect+FF
Поэтому демо на VK. дяденька не бань UPD: уязвимость исправили.
1. У вас не должно быть привязанного VK. Авторизуйтесь oauth.vk.com/authorize?response_type=code&client_id=3110645&redirect_uri=http%3A%2F%2Fhabrahabr.ru&scope=offline&display=page
2. Вас вернуло на habrahabr.ru/?code=CODE
3. Заставьте другого хабраюзера посетить habrahabr.ru/social/callback/vkontakte/?code=CODE&state=whogivesafuckaboutstate можно подкинуть саму ссылку, но лучше спрятать в img или iframe и тд. Если он залогинен на хабре ваш ВК привяжен к его хабрааккаунту.
4. Логинимся через ваш ВК в его хабрааккаунт, меняем его аватар на nayncat.
Мораль
Вконтакте: перестаньте игнорировать письма в Поддержку, либо попросите ваших разработчиков снизойти поговорить с простым смертным. А еще введите bounty program (sarcasm: есть риск разориться на ней).
Хабр: рекомендую выключить Ключницу на время и пофиксить уязвимость путем правильной проверки ‘state’ со значением из cookie/session.
Road to Hell короче. Вы можете присоедениться к разработке принципиально нового стандарта с нескучными токенами — OAuth2.a (Charm — Provider). Печенек, правда, нет.
Egor Homakov (@homakov) & isciurus #RT pls
↩️ «Выйди и снова зайди, только правильно». Всё ли вы знаете об OAuth 2.0?
Социальные сети, потоковая передача контента, воркспейсы – везде мы заходим через учетные записи, которые могут содержать личную информацию. Изолированные приложения становятся взаимосвязанными: Twitter позволяет новостным сайтам твитить напрямую, Discord ищет предполагаемых друзей на Facebook, а Jira создает учетки с помощью профилей Github.
Раньше для авторизации сайты и приложения использовали простую схему логин/пароль. Это существенно усложняло задачу взаимодействия приложений: чтобы позволить приложению получить доступ к данным другого приложения, требовалось передать учетные данные. Но это порождало множество проблем, связанных с небезопасным хранением учетных данных и получением неограниченного доступа. Для обеспечения делегированного доступа был создан открытый протокол авторизации OAuth.
Терминология OAuth
Разберем несколько общих терминов. Для упрощения под OAuth будем подразумевать OAuth 2.0.
Функционирование протокола OAuth
В том же ключе OAuth используется в социальных сетях. Например, при авторизации в Spotify через Facebook приложение Spotify получает доступ лишь к ограниченному набору данных.
Рис. 1. Используя OAuth, клиент (Spotify) может получить доступ к ресурсному серверу (Facebook) без учетных данных от имени владельца ресурса (Боба).
При выводе всплывающего окна OAuth работает в фоновом режиме (Рис. 2):
Заглянем под капот OAuth
Области и токены OAuth
Области и токены OAuth реализуют детализированное управление доступом. Похоже на киносеанс: область – название фильма, который вы имеете право смотреть, токен – билет, что может проверить лишь сотрудник конкретного кинотеатра.
Вернемся к Рис. 2. Сервер авторизации имеет API, отличающийся от ресурсного сервера. Сервер авторизации служит для проверки и авторизации клиента, в то время как сервер ресурсов хранит запрашиваемые ресурсы. Чтобы ресурсный сервер знал, следует ли выполнять запрос на получение информации, он должен знать, авторизован ли запрашивающий. Тут и появляется токен, чтобы сообщить серверу ресурсов, что запрашивающий был проверен сервером авторизации и имеет разрешение на выполнение запроса. При использовании токенов в качестве прокси-сервера необходимость предоставления учетных данных отпадает. Данные маркеры зашифрованы, но при декодировании сервером ресурсов из них можно вытащить значение области.
Условно можно выделить четыре типа областей:
Рис. 3. OAuth поток
Разрешения и потоки OAuth
Возвращаясь к аналогии с кинотеатром, есть два способа получить билет: покупка в кинотеатре и покупка онлайн. Выбранный метод влияет на последовательнось действий для получения билета. Покупка в театре выглядит так:
Разрешения (grants) диктуют клиенту порядок операций по получению access-токена. Этот уникальный порядок называется потоком.
Вся коммуникация между владельцем ресурса, клиентом и сервером авторизации происходит через строки запроса с параметрами. В этих параметрах содержится информация, необходимая серверу авторизации для понимания того, какому потоку следовать:
Пример: GitHub SSO
Изучим описанные концепции на примере. Teleport – опенсорсный инструмент удаленного доступа, позволяющий юзерам входить в систему через Github single sign-on (SSO) с использованием OAuth. Действующие лица :
Рассмотрим поток шаг за шагом.
Шаг 1. Пользователь Teleport получает доступ к приложению Teleport.
Шаг 2. Приложение предлагает пользователю Teleport войти с помощью Github SSO.
Шаг 3. Пользователь Teleport нажимает «Войти» и перенаправляется на другую страницу со своими параметрами, передаваемыми в HTTPS GET запросе:
Собрав воедино все, получим следующую строку приглашения:
Шаг 4. Как только GAS получит запрос, он проверит client_id в реестре. Зная, что Teleport ожидает код авторизации, GAS отправит пользователя обратно на URL-адрес с переданными параметрами:
Шаг 7. Теперь, когда маркер получен, делаем запрос к API от имени пользователя Teleport и получаем желаемое:
Шаг 8. Н аконец, GitHub API пропускает юзера.
Заключение
Несмотря на часто упускаемое из виду удобство, OAuth-это сложный протокол, реализация которого потребует времени. Пример, который мы рассмотрели выше – один из сотен вариантов того, как может выглядеть поток OAuth.
Если вы увлеклись веб-разработкой, но ищите помощь наставника, мы советуем обратить внимание на курс факультета Веб-разработки GeekBrains, где вы получите готовую базу навыков и необходимую поддержку. Кстати, на курсе большое внимание уделяется безопасности как клиентской, так и серверной части веб-приложения.
Курс поможет освоить профессию веб-разработчика, получить диплом и создать портфолио с рабочими проектами. В случае успешного прохождения команда университета поможет с трудоустройством. Ознакомиться с программой и отзывами можно, нажав расположенную ниже кнопку.
OAuth на практике. Аутентификация и авторизация пользователей сайта через популярные социалки
Почему OAuth, а не OpenID?
Потому что OpenID практически бесполезен для тех целей, для которых декларирован. Это сугубо мое мнение, но оно опирается не на пустое место.
Во-первых, OpenID пользуются в основном «гики», процент которых в интернете не настолько высок, чтобы перестраивать под них сайты (за некоторым исключением, разумеется 🙂 ) Почему так? Потому что для того, чтобы получить OpenID аккаунт, надо — его получить. Зайти на OpenID сервер и предпринять некоторые действия, чтобы заполучить некий, довольно невразумительный, набор символов. Который, несмотря на сложность (для простого пользователя) надо не забыть и вводить при случае, если на глаза попадется знакомая пиктограмма . Ну какой казуальный пользователь будет это делать? А с OAuth все намного проще — видит человек кнопку «Войти через ВКонтакте», нажимает, и… уже на сайте с правами зарегистрированного пользователя. «Будьте проще», — говорил классик, — «и люди к вам потянутся». Как в воду глядел.
Во-вторых, возможности OAuth далеко не исчерпываются аутентификацией и авторизацией. Получив в процессе авторизации токен, его можно использовать для дальнейшей интеграции возможностей социалки в свой ресурс — чтение/написание постов, доступ к френдленте и стене и многое другое.
В-третьих, OpenID активно пользуются спамеры и хакеры. Зачастую реализация OpenID аутентификации на ресурсе делается без особого внимания к известным его уязвимостям — по одному только описанию протокола на OpenID-провайдере или с помощью неизвестно кем и когда написанной библиотеки. К примеру, многие сайты не требуют со входящих по OpenID ввода капчи. И ничто не мешает злоумышленнику поднять свой OpenID-сервер, который будет подтверждать любой идентификатор и начать спамить доверчивый сайт автоматически сгенеренными идентификаторами. Кроме того, OpenID аутентификация, в сущности, не дает никаких гарантий клиенту. Она подтверждает лишь, что запрашиваемый пользователь действительно зарегистрирован на одном из OpenID-серверов — и все. Механизмы получения дополнительной информации о пользователе (email, имя, возраст) имеются, но мало кем поддерживаются. Можно, конечно, в нарушение идей OpenID, анализировать идентификатор и доверять только определенным OpenID-провайдерам (например, тем же социалкам). Но смысл, если почти все из них (за исключением ЖЖ, но он и по OpenID ровным счетом ничего не расскажет о пользователе) поддерживают OAuth, который позволяет получить намного больше информации? Так что со всех своих сайтов я вообще убрал поддержку OpenID.
Почему OAuth, а не виджет «Войти через»?
Нет проблем. Если вас устраивают функционал, дизайн и уровень безопасности виджета — то его воткнуть в код на самом деле намного проще — можете дальше не читать.
Как это работает.
Почему сырой HTTP, а не куски кода с использованием OAuth библиотеки?
Потому что я порядком помучался, вытаскивая этот самый сырой HTTP зачастую и из кусков кода, иллюстрирующих использование той или иной библиотеки. Конкретная реализация OAuth на каждом сервере имеет свои тонкости, перед которыми может спасовать даже самая гибкая библиотека. Кроме того, веб-языков много, библиотек — еще больше, дать примеры на все просто нереально. А сырого HTTP (при наличии мозгов) вполне достаточно для использования любой библиотеки. Чего не скажешь об обратном случае.
Практические рекомендации по реализации
Разумеется, в первую очередь надо зарегистрироваться в соцсети, активировать аккаунт, ну и всё такое. Не торопиться. Некоторые сервера не сразу корректно обрабатывают запросы от свежезарегистрированных OAuth-клиентов. Здесь я расписал только успешные потоки, забывать про обработку ошибок — никак не стоит. Также я практически не уделил внимания аспектам безопасности — это тема отдельной статьи. Как минимум, везде, где можно передавать уникальный параметр в callback-url для каждого пользователя — это стоит делать (Основной callback адрес должен оставаться без изменений, а меняться — только параметр, иначе сервер не пропустит запрос. Особо обратите на это внимание, если у вас стоит mod_rewrite), как и пользоваться параметром state для передачи дополнительных данных callback-скрипту (там, где этот параметр поддерживается). Я все это пока оставил за скобками.
ВКонтакте
GET https://oauth.vk.com/access_token?client_id=
&client_secret= & code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a//полученный в параметрах код
3.4. В ответ на это (опять же в случае успеха) мы получаем опять-таки JSON список перечисленных параметров. Что нам и нужно было. Имя пользователя — в utf8, город и регион — в виде кодов, названия надо получать вызовом отдельного метода с укаазнием кода.
Полный список того, чего можно запросить, можно взять здесь. Полный список методов API ВКонтакте здесь.
Одноклассники
Да-да, часть подписи кодится дважды.
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — utf8;
Полный список возвращаемых параметров функции users.getCurrentUser здесь. Описание API здесь. Но сразу предупреждаю, что автор его был болен рассеянным склерозом в последней стадии, поэтому о многих аспектах использования той или иной функции надо просто догадываться.
Facebook
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — NFC юникод (в виде \u0410\u0401\u0419)
Список функций API (и возвращаемых данных) здесь.
Twitter
1. Идем сюда и регаем новое приложение. Вводим имя, описание, наш сайт и урл скрпита-обработчика. На странице настроек нажимаем кнопку «Create my access token».
Дальше слов нет, сплошные эмоции. Горечь и боль переполняют меня. Ну зачем же они так. Рекомендую для начала натравить на twitter какую-нибудь OAuth-библиотеку. И только, если ничего не получится (лично у меня не получилось подружить Net::OAuth с твиттером) вооружаемся терпением и лезем разбираться.
1. Здесь OAuth 1.0 и тут всё веселее. При нажатии пользователем кнопки «Зайти через Twitter» мы запускаем скрипт, который выполняет POST-запрос на
Authorization:OAuth oauth_callback=«http%3A%2F%2Fmysite.com%2Ftwlogin», oauth_consumer_key=»
«, oauth_nonce=» «, oauth_signature_method=«HMAC-SHA1», oauth_timestamp=»
Authorization:OAuth oauth_consumer_key=»
«, oauth_nonce=» «, oauth_signature_method=«HMAC-SHA1», oauth_timestamp=»
Authorization:OAuth oauth_consumer_key=»
«, oauth_nonce=» «, oauth_signature_method=«HMAC-SHA1», oauth_timestamp=»
3.4. В случае успеха нам приходит JSON-список параметров, содержащий имя, фото и пр. Полный список функций API и их описания здесь.
Mail.ru (МойМир)
в виде hex string.
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — utf8;
Список функций API (и описания) здесь.
Яндекс
чего не наблюдалось в ответах от других сайтов. Тут явно ошибка библиотеки, RFC на JSON не запрещает лишние пробелы, но на всякий случай обращаю внимание — вдруг кто-то еще споткнется на этом.
Описание API yandex.login здесь.
Google
3.4. В ответ получаем JSON-список запрошенных параметров.
Описание API работы с гугл-контактами здесь.
На этом пока все. Думаю, даже самые нелюдимые пользователи рунета имеют аккаунт хотя бы на одном из вышеупомянутых серверов.
Надеюсь, статья поможет тем, кто хочет сделать на своем сайте регистрацию по OAuth. Во всяком случае, попадись мне такая статья раньше, я бы сэкономил кучу времени и сил.
Я реализовывал это всё на perl, соответственно, если у кого возникнут вопросы по реализации OAuth на перле — могу дать свои рекомендации. По другим языкам — увы.