Секрети OAuth у мобільних додатках


137

Під час використання протоколу OAuth вам потрібна секретна рядок, отримана від служби, якій потрібно делегувати. Якщо ви робите це у веб-додатку, ви можете просто зберігати секрет у вашій базі даних або у файловій системі, але який найкращий спосіб обробити його в мобільному додатку (або настільному додатку з цього питання)?

Зберігання рядка в додатку, очевидно, не є гарним, оскільки хтось легко може його знайти і зловживати ним.

Інший підхід полягає в тому, щоб зберігати його на вашому сервері та додавати програму під час кожного запуску, ніколи не зберігаючи її на телефоні. Це майже так само погано, адже вам потрібно включити URL-адресу в додаток.

Єдине дієве рішення, яке я можу придумати, - спершу отримати токен доступу як звичайний (бажано, використовуючи веб-перегляд всередині додатка), а потім прокласти все подальше спілкування через наш сервер, який додасть секрет до даних запиту та спілкуватиметься з провайдером. Знову ж таки, я нобі-охоронець, тому мені дуже хотілося б почути думки людей з цього приводу. Мені не здається, що більшість додатків збираються настільки довго, щоб гарантувати безпеку (наприклад, Facebook Connect, здається, припускає, що ви вводите секрет у рядок прямо у вашому додатку).

Інша річ: я не вірю, що секрет пов'язаний з тим, щоб спочатку запросити маркер доступу, щоб це можна було зробити без залучення власного сервера. Я прав?


Вибачте, якщо я не зрозуміла, але яка проблема зі зберіганням кодів у базі даних програми? Оскільки ці жетони генеруються та зберігаються після того, як користувач підтвердив автентифікацію свого облікового запису, тому слід з впевненістю вважати, що зазначений користувач хоче, щоб мобільний пристрій зберігав доступ, щоб мати доступ.
ткнути

Навіть після того, як користувач дозволив вам отримати доступ до свого облікового запису (у Twitter, скажімо), ви повинні використовувати секрет, який ви отримали від служби, до якої ви намагаєтесь отримати доступ. Цей секрет використовується у всіх комунікаціях зі своїм сервером, разом із ключем аутентифікації та деякими іншими ключами. Так, так, ви можете зберігати ключ доступу, але секрет не повинен зберігатися, оскільки його можна використовувати з будь-яким ключем аутентифікації для зловживання службою. Знову радий, мене виправлять люди, які більше про це знають.
Феліксиз

1
OAuth пропонує метод аутентифікації, який захищає вихідні дані для входу користувача. Щоб зробити це можливим, створюється нова унікальна комбінація входу, яка працює лише разом з комбінацією клавіш унікальної програми. Велика перевага від зберігання даних для входу користувача полягає в тому, що вони повністю безпечні після першого авторизації, і в будь-якому випадку порушення може просто відкликати доступ авторизації. І звичайно, збереження секрету не має сенсу, оскільки користувачеві потрібно буде повторно підтвердити автентифікацію (і це не те, що користувач хоче, надаючи додатку доступ).
ткнути

@poke Ключ автентифікації, отриманий, коли користувач схвалює ваш додаток з постачальником, слід зберігати, але секретний маркер, який ви отримали від постачальника перед випуском програми, не повинен (у випадку настільного або мобільного додатка; якщо це веб-додаток, очевидно, ви можете зберігати ключ на сервері, як зазначено в запитанні).
Феліксиз

4
Згідно з моїм розумінням oAuth - У випадку настільного додатка дуже легко нюхати / відстежувати трафік HTTP / HTTPS за допомогою таких інструментів, як цей ieinspector.com/httpanalyzer/index.html Звідси ваш секрет маркера та маркера можна знайти дуже легко. Тож єдиний захист - це ваша таємниця споживачів. Тепер, якщо ваш магазин зберігає секрет всередині додатка, і хтось зможе його знайти, це стає дитячою грою, щоб видати себе за будь-який інший додаток як ваш додаток. Виправте мене, якщо я помиляюся.
Варун

Відповіді:


38

Так, це проблема з дизайном OAuth, з яким ми стикаємося самі. Ми вибрали проксі-сервер усіх дзвінків через власний сервер. Щодо настільних додатків OAuth не був повністю розмитий. Немає префектного вирішення питання, яке я знайшов, не змінюючи OAuth.

Якщо ви задумаєтесь над цим і задаєте питання, чому у нас є секрети, це здебільшого для забезпечення додатків та вимкнення програм. Якщо наш секрет порушений, то постачальник може лише реально відкликати весь додаток. Оскільки нам належить вставити свою таємницю в настільний додаток, ми начебто накручені.

Рішення полягає в тому, щоб мати різний секрет для кожного настільного додатка. OAuth не робить цю концепцію легкою. Один із способів полягає в тому, щоб користувач перейшов і створив секрет самостійно і ввів ключ самостійно у свій настільний додаток (деякі програми facebook робили щось подібне протягом тривалого часу, змусивши користувача зайти та створити facebook, щоб налаштувати свої власні вікторини та лайно). Це не великий досвід для користувача.

Я працюю над пропозицією щодо системи делегування OAuth. Концепція полягає в тому, що, використовуючи власний секретний ключ, який ми отримуємо від нашого постачальника, ми можемо видавати власний делегований секрет власним настільним клієнтам (по одному для кожного додатка на робочому столі), а потім під час процесу авторизації ми пересилаємо цей ключ на верхній рівень постачальника, який дзвонить нам і повторно підтверджує. Таким чином ми можемо відкликати власні секрети, які ми видаємо кожному клієнтові робочого столу. (Позичив багато, як це працює від SSL). Вся ця система була б префектом для веб-сервісів з додатковою вартістю, а також передає дзвінки сторонній веб-службі.

Процес також може бути здійснений без зворотних зворотів для підтвердження делегування, якщо постачальник вищого рівня надає API для створення та відкликання нових делегованих секретів. Facebook робить щось подібне, дозволяючи програмам facebook дозволяти користувачам створювати додатки.

Деякі розмови щодо цього питання в Інтернеті:

http://blog.atebits.com/2009/02/fixing-oauth/ http://groups.google.com/group/twitter-development-talk/browse_thread/thread/629b03475a3d78a1/de1071bf4b820c14#de1071bf4b820c14

Рішення Twitter та Yammer - це контактне рішення для автентифікації: https://dev.twitter.com/oauth/pin-based https://www.yammer.com/api_oauth_security_addendum.html


Це дуже цікаво, хоча це підтверджує те, чого я побоювався, що OAuth не настільки чудовий для настільних / мобільних додатків. Звичайно, зловмиснику доведеться спершу отримати секрет, а потім також обнюхати чиїсь повноваження, тож це зайняло б певне визначення. Розробка штифтів нормально для робочого столу, але для мобільних iMO важко.
Феліксиз

Як ваша запропонована схема допоможе веб-сервісам з додатковою вартістю, оскільки ця проблема не стосується їх? Крім того, я не бачу, як би це працювало з провайдером, який створює нові секрети, оскільки вам знадобиться "головний секрет", щоб навіть запитувати ці нові секрети, тож вам хоч би знадобився один дзвінок на ваш власний сервер (у якому зберігається головний секрет). Але це, звичайно, краще, ніж маршрутизація всього трафіку через власний сервер. Роз'яснення вітаємо! І будь ласка, оновіть тут по мірі просування вашої пропозиції!
Феліксиз

5
Просто цікаво: як ви визначите, що те, що робить дзвінок на ваш проксі-сервер, є законним?
davidtbernal

1
У відповідь на notJim: першочерговий ризик дозволити вашій споживчій таємниці вийти з-за того, що зловмисні (або нерозумні) додатки можуть бути розроблені з його допомогою, погіршуючи вашу репутацію та збільшуючи ризик відключення вашої законної програми для зловживання / неправильного використання API. Отримавши доступ до всіх дзвінків, які потребують вашої таємниці, через веб-додаток, яким ви керуєте, ви знову в положенні, де ви можете спостерігати за зловживаннями та скасовувати доступ на користувачеві або на рівні маркера доступу до того, як API, який ви споживаєте, вирішить закрити весь ваш сервіс.
квазістоїк

Я погоджуюся з квазістоїчним тут, вам потрібно буде використовувати браузер з підтримкою SSL, щоб мати справу з викликом oauth. Це добре з кількох причин, серед яких легко керувати будь-якими оновленнями безпеки в майбутньому, і нічого в реальній програмі не потрібно буде оновлювати з часом. Зак вказує, що Твіттер пропонує рішення PIN-коду, яке я насправді придумав, тому що ви не можете довіряти програмі надійно отримати код. Я пропоную використовувати "Nonce" із сучасним шифруванням разом із PIN-кодом та секретом для проксі-запиту через веб-сервер.
Марк

18

За допомогою OAUth 2.0 ви можете зберігати секрет на сервері. Використовуйте сервер, щоб придбати маркер доступу, який ви перемістите в додаток, і ви зможете здійснювати дзвінки з програми на ресурс безпосередньо.

За допомогою OAuth 1.0 (Twitter) секрет необхідний для здійснення дзвінків API. Проксі-сервер дзвінків через сервер - єдиний спосіб запобігти невзбиранню секрету.

Обидва вимагають певного механізму, за яким ваш серверний компонент знає, що ваш клієнт викликає його. Це, як правило, робиться при встановленні та використанні певного механізму платформи, щоб отримати якийсь ідентифікатор програми у виклику на ваш сервер.

(Я редактор специфікації OAuth 2.0)


2
Чи можете ви розробити "механізм, визначений для платформи, щоб отримати якийсь ідентифікатор програми"? Як серверний компонент перевіряє особу клієнта? Я думаю, що це можна зробити із забезпеченням клієнтів. Наприклад, розгорнути новий та унікальний сервер SSL для кожного клієнта. Це ви маєте на увазі? Якщо це складніше, ніж це, можливо, ви можете звернутися до більш поглибленого запису?
Cheeso

2
Я пригадую, як деякі охоронці розмовляли про те, як це можна зробити. Існує дзвінок в ОС, який повертає підписаний маркер, який ви можете потім надіслати на ваш сервер і підтвердити. Вибачте, у мене немає специфіки. Це помилка, яка може використовувати кілька хороших прикладів.
Дік Хардт

2
@DickHardt, але як у цьому сценарії ви гарантуєте, що мобільний додаток справді ваш додаток, а не шахрайський?
Рафаель Мембрівс

11

Одним з рішень може бути жорсткий код секрету OAuth у код, але не як звичайний рядок. Заплутайте його якимось чином - розділіть його на сегменти, змістіть персонажів за зміщенням, обертайте - виконайте будь-які чи всі ці речі. Зломщик може проаналізувати ваш байт-код і знайти рядки, але код обфускування може бути важким для з'ясування.

Це не дурне захисне рішення, а дешеве.

Залежно від цінності експлуату, деякі геніальні сухарі можуть піти на більшу відстань, щоб знайти свій секретний код. Вам потрібно зважити фактори - вартість раніше згаданого рішення на стороні сервера, стимул для сухарів витратити більше зусиль на пошук свого секретного коду та складність обскудації, яку ви можете застосувати.


1
Так, я думаю, що це розумно. Потрібно було б багато рішучості, щоб хтось спочатку витягнув споживчу таємницю, а потім викрав повноваження людей, щоб зробити щось значне. Для гучних додатків я не впевнений, що цього буде достатньо, але для середнього додатка, я думаю, ви праві, що вам доведеться збалансувати час впровадження проти досить незначної загрози безпеці.
Феліксиз

7
Все, що потрібно, - це один користувач докласти зусиль, а потім опублікувати або поділитися своєю таємницею. Після того, як ваша таємниця вимкнеться, ризик вас повністю закрити, щоб зловживати зловживаннями, і це повністю вийде з вашого контролю.
квазістоїчний

8
Заплутаність - це взагалі не безпека. Це гірше, ніж взагалі немає безпеки, оскільки це дає розробнику помилкове відчуття безпеки. en.wikipedia.org/wiki/Security_through_obscurity
Пол Легато

8
"Обфузація - це взагалі не безпека. Це гірше, ніж взагалі немає безпеки, оскільки це дає розробнику помилкове відчуття безпеки". Дурниці. Ніхто не каже, що затуманення забезпечує добру безпеку. Але якщо я збираюся розповсюджувати секрет OAuth своїм apk, то, безумовно, краще затуманити, ніж ні. Захоплення - це те, що Google також рекомендує зберігати ключі / секрети в додатку. Якщо нічого іншого, ці заходи тримають випадкових хакерів у страху, що краще, ніж нічого. Бланкетні твердження, як і ваш, прирівнюють недосконалу безпеку без захисту. Це просто неправда. Недосконале - просто недосконале.
голодний

1
Обфузація НЕ допомагає, тому що незалежно від того, скільки зсуву чи кодування ви робите, ви все одно будуєте ключ разом і використовуєте його для створення свого запиту API. Досить просто динамічно підключити API в потрібних місцях, щоб скинути запит, який ви надсилаєте, ще до шифрування HTTPS. Тому, будь ласка, не вставляйте секретні ключі у свою програму, якщо насправді немає альтернативи.
C0deH4cker

6

Не зберігайте секрет всередині програми.

Потрібно мати сервер, до якого програма може отримати доступ через https (очевидно), і ви зберігаєте на ньому секрет.

Коли хтось захоче ввійти через ваш мобільний / настільний додаток, ваш додаток просто пересилає запит на сервер, який потім додасть секрет та надішле його постачальнику послуг. Потім ваш сервер може повідомити вашу програму, чи вдала вона чи ні.

Тоді, якщо вам потрібно отримати будь-яку конфіденційну інформацію з сервісу (facebook, google, twitter тощо), програма запитає ваш сервер, і ваш сервер передасть її до програми, лише якщо вона правильно підключена.

Насправді немає жодного варіанту, окрім зберігання на сервері. Ніщо на стороні клієнта не є безпечним.

Примітка

При цьому це захистить вас лише від зловмисного клієнта, але не від клієнта від зловмисного вас, а не від інших зловмисних клієнтів (фішинг) ...

OAuth - набагато кращий протокол у браузері, ніж у настільному / мобільному.


1
чи це не полегшує життя хакера ?! тому що зараз для доступу до ресурсів сервера нам технічно потрібен ідентифікатор клієнта, оскільки сервер все одно додасть секрет до запиту. я щось пропускаю?
Худі

@HudiIlfeld Так, вам щось не вистачає: клієнту потрібно увійти на сервер. Поки він не входить в систему, сервер нічого не поверне. Один із способів управління цим - після першого надсилання облікового запису, сервер повертає маркер доступу клієнту, а потім клієнт надсилає цей маркер доступу з кожним майбутнім запитом. Тут є багато варіантів.
Гудрадейн

4

Існує нове розширення до типу наданого коду авторизації під назвою ключ підтвердження для обміну кодом (PKCE) . З цим вам не потрібен секрет клієнта.

PKCE (RFC 7636) - це техніка захисту публічних клієнтів, які не використовують секрет клієнта.

Її в основному використовують рідні та мобільні додатки, але ця техніка може бути застосована і до будь-якого публічного клієнта. Він вимагає додаткової підтримки з боку сервера авторизації, тому він підтримується лише певними постачальниками.

з https://oauth.net/2/pkce/

Для отримання додаткової інформації ви можете прочитати повний RFC 7636 або це коротке вступ .


2

Тут є над чим подумати. Google пропонує два методи OAuth ... для веб-додатків, де ви реєструєте домен і генеруєте унікальний ключ, а також для встановлених програм, де ви використовуєте ключ "анонімний".

Можливо, я прочитав щось у читанні, але здається, що обмін унікальним ключем вашого веб-сайту з встановленим додатком, ймовірно, більш безпечний, ніж використання "анонімного" в офіційному методі встановлених додатків.


2

За допомогою OAuth 2.0 ви можете просто використовувати потоки на стороні клієнта, щоб отримати маркер доступу, а потім використовувати цей маркер доступу для автентифікації всіх подальших запитів. Тоді вам взагалі не потрібен секрет.

Приємний опис того, як це реалізувати, можна знайти тут: https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#mobile-apps


За умови, що послуга підтримує "клієнтський потік". Багато хто з них не вимагає ідентифікатора клієнта та секретаріату клієнта для отримання цього маркера доступу.
Даміан Єррік

0

Я не маю багато досвіду роботи з OAuth - але чи не кожен запит вимагає не лише маркера доступу користувача, але і споживчого ключа та секрету програми? Тож, навіть якщо хтось викраде мобільний пристрій і намагається витягнути з нього дані, їм також знадобиться ключ програми та секрет, щоб мати можливість реально робити що-небудь.

Я завжди думав, що намір за OAuth полягає в тому, щоб кожен Том, Дік та Гаррі, які мали мешанку, не повинні зберігати ваші облікові дані Twitter. Я думаю, що це досить добре вирішує цю проблему, незважаючи на обмеження. Крім того, він насправді не був розроблений з урахуванням iPhone.


Ви маєте рацію, OAuth був здебільшого розроблений з урахуванням веб-додатків, і я впевнений, що це добре працює для цього. Так, для підписання кожного запиту вам потрібен споживчий маркер та секрет, і проблема полягає в тому, де зберігати секрет. Якщо хтось викраде ключ доступу, це не велика справа, оскільки його можна відкликати, але якщо хтось отримує споживчий ключ, кожна копія вашої програми була порушена.
Феліксиз

OAuth 1 вимагає підписання кожного запиту. OAuth 2 вимагає лише маркер доступу. Обидва вимагають ключ та секрет при придбанні жетону.
Дік Хардт

0

Я згоден з Феліксизом. У той час як OAuth краще, ніж Basic Auth, все ще має пройти довгий шлях, щоб стати гарним рішенням для мобільних додатків. Я грав із використанням OAuth для аутентифікації програми мобільного телефону в додатку Google App Engine. Те, що ви не можете надійно керувати споживчою таємницею на мобільному пристрої, означає, що за замовчуванням використовується "анонімний" доступ.

Крок авторизації веб-переглядача впровадження Google App Engine OAuth перенаправляє вас на сторінку, де він містить текст на зразок: "Сайт <сайт-просити> вимагає доступу до вашого облікового запису Google для продуктів, перелічених нижче".

YourApp (yourapp.appspot.com) - не пов’язаний з Google

тощо

<some-site> з домену / імені хоста, використовуваного в URL-адресі зворотного дзвінка, який ви надаєте, який може бути будь-яким на Android, якщо ви використовуєте власну схему для перехоплення зворотного дзвінка. Отже, якщо ви використовуєте "анонімний" доступ або ваша конфіденційність споживача порушена, тоді будь-хто може написати споживача, який обдурить користувача, щоб отримати доступ до вашої програми gae.

Сторінка авторизації Google OAuth також містить безліч попереджень, які мають 3 рівні суворості залежно від того, використовуєте ви "анонімні", таємниці споживачів або відкриті ключі.

Досить страшні речі для пересічного користувача, який не є технічно кмітливим. Я не сподіваюся, що у вас є високий відсоток завершення реєстрації з подібними матеріалами.

У цьому дописі в блозі роз'яснено, як секрет споживачів насправді не працює з встановленими програмами. http://hueniverse.com/2009/02/should-twitter-discontinue-their-basic-auth-api/


0

Я також намагаюся розробити рішення для аутентифікації мобільного OAuth та загального зберігання секретів у пакеті додатків.

І божевільна ідея мене просто вразила: найпростіша ідея - це зберігати секрет всередині двійкового, але затуманений якось, або, іншими словами, ви зберігаєте зашифровану таємницю. Отже, це означає, що вам потрібно зберегти ключ для розшифровки вашої таємниці, який, здається, зайняв нас повним колом. Однак чому б не просто використовувати ключ, який вже є в ОС, тобто він визначений ОС, а не вашою програмою.

Отже, для уточнення моєї ідеї є те, що ви вибираєте рядок, визначений ОС, не має значення, яку саме. Потім зашифруйте свою таємницю, використовуючи цей рядок як ключ, і збережіть її у вашому додатку. Потім під час виконання розшифруйте змінну за допомогою ключа, який є лише постійною ОС. Будь-який хакер, який заглядає у ваш двійковий файл, побачить зашифрований рядок, але жодного ключа.

Це буде працювати?


3
Гарна думка, але ні. Зломщик просто побачив бинарний, який вказує на адресу константи ОС.
GrayB


0

Facebook не застосовує OAuth строго кажучи (поки), але вони реалізували спосіб, щоб ви не вставляли свою таємницю в додаток для iPhone: https://web.archive.org/web/20091223092924/http://wiki. developers.facebook.com/index.php/Session_Proxy

Щодо OAuth, так, чим більше я думаю про це, ми трохи забиті. Можливо, це виправить.


1
wiki.developers.facebook.com мертвий.
Гюго

0

Жодне з цих рішень не заважає певному хакеру нюхати пакети, відправлені зі свого мобільного пристрою (або емулятора) для перегляду клієнтської таємниці у заголовках http.

Одним з рішень може бути динамічний секрет, який складається із часової позначки, зашифрованої приватним двостороннім ключем та алгоритмом шифрування. Потім служба розшифровує секрет і визначає, чи марку часу становить +/- 5 хвилин.

Таким чином, навіть якщо секрет порушений, хакер зможе користуватися ним лише максимум 5 хвилин.


-2

Як зазначали інші, зі зберіганням секрету локально на пристрої не повинно виникати справжніх проблем.

Крім того, ви завжди можете розраховувати на модель безпеки Android на основі UNIX: лише ваша програма може отримати доступ до того, що ви пишете у файловій системі. Просто запишіть інформацію в об'єкт SharedPreferences за замовчуванням для програми.

Щоб отримати секрет, потрібно було б отримати кореневий доступ до телефону Android.


3
Як хто згадав? Якщо ви маєте на увазі коментар Poke, дивіться мою відповідь таємно! = Ключ автентифікації. Останні можна безпечно зберігати, перші не можуть. Я не знаю про Android, але отримати кореневий доступ до iPhone зовсім не важко. Зауважте, що секрет однаковий у всіх екземплярах програми, тому зловмиснику доведеться отримати доступ лише до одного бінарного файлу. І навіть якщо вони не змогли отримати доступ до кореневого пристрою на пристрої, вони могли б дістати руки до бінарного файлу в якомусь іншому та витягнути з нього таємний маркер.
Феліксиз

1
просто додати,
корінгові
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.