Захищеність схем аутентифікації REST


228

Фон:

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

Ці питання ТА були особливо корисними для того, щоб почати мене:

Я думаю про використання спрощеної версії аутентифікації Amazon S3 (мені подобається OAuth, але це здається занадто складним для моїх потреб). Я додаю до запиту випадково згенерований безвіз , наданий сервером, щоб запобігти повторним атакам.

Щоб перейти до питання:

І S3, і OAuth покладаються на підписання URL-адреси запиту разом із кількома вибраними заголовками. Жоден з них не підписує орган запиту на запити POST або PUT. Чи не вразлива ця атака "посередника", яка зберігає URL-адресу та заголовки та замінює орган запиту будь-якими даними, які зловмисник хоче?

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


6
Amazon S3 може включати Content-MD5 як частину рядка заголовка, щоб запобігти атаці MITM, яку ви описуєте.
лаз

8
MD5 - це дуже слабка хеш-функція, і її використання вже не перешкоджає вже багато років: en.wikipedia.org/wiki/MD5 . Використовуйте SHA2 сьогодні. MD5 - помада на свині з кризою особи.
Генрік

6
Startcom надає безкоштовні сертифікати SSL, які не викидають попередження про сертифікати у великих браузерах
Платон

5
@SeanKAnderson (rant: мені здається абсурдним, як люди говорять про 99,99999% s, коли Інтернет знаходиться під облогою шпигунських агентств, які вже в 2008 році автоматизували багато атак - це такий дивний спосіб вирішити справжню проблему - "Naaah, це не буде проблемою; для моєї бабусі не вдасться її зламати"
Генрік

2
@Plato Я б рекомендував LetsEncrypt в ці дні для безкоштовних сертифікатів SSL
shuttle87

Відповіді:


168

Попередня відповідь згадала лише SSL в контексті передачі даних і фактично не охоплювала аутентифікацію.

Ви справді запитуєте про надійну автентифікацію клієнтів REST API. Якщо ви не використовуєте автентифікацію клієнта TLS, тільки SSL НЕ є життєздатним механізмом аутентифікації для API REST. SSL без клієнта authc тільки автентифікує сервер , що не має значення для більшості API REST, оскільки ви дійсно хочете перевірити автентифікацію клієнта .

Якщо ви не використовуєте автентифікацію клієнта TLS, вам потрібно буде використовувати щось на зразок схеми автентифікації на основі дайджестів (наприклад, спеціальна схема веб-служби Amazon) або OAuth 1.0a або навіть автентифікацію HTTP Basic (але тільки для SSL).

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

Для тих, хто цікавиться, я розширив питання про схему аутентифікації HTTP та як вони працюють .


16
Саме так. Єдине, що SSL підтверджує, що стосується вашого API - це те, що дзвінок, з яким він має справу, не був зіпсований по дорозі. API все ще не має уявлення, хто з ним розмовляє, чи повинен вони взагалі мати доступ.
Тім Готьє

1
Хороша відповідь. Я також рекомендую поглянути на ці чудові ресурси .. owasp.org/index.php/Web_Service_Security_Cheat_Sheet та owasp.org/index.php/REST_Security_Cheat_Sheet (DRAFT)
dodgy_coder

2
Лише незначний момент, але використання SSL також має додаткову перевагу у запобіганні підслуховування та потрапляння людей у ​​атаку посередині.
dodgy_coder

@Les Hazlewood Чи можете ви пояснити, як автентифікація HTTP Basic за допомогою Https може допомогти визначити, хто сервер знає, з ким він спілкується?
Весна

@Les Hazlewood тут я задав це питання; tnx stackoverflow.com/questions/14043397/…
Весна

60

REST означає роботу зі стандартами Інтернету, а стандартом для "безпечної" передачі в Інтернеті є SSL. Все інше буде нестим і вимагає додаткових зусиль для розгортання для клієнтів, для чого доведеться мати бібліотеки шифрування.

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

HTTP Digest - це більш безпечний підхід, оскільки запобігає передачі секретного маркера; натомість це хеш, який сервер може перевірити на іншому кінці. Хоча це може бути непосильним для менш чутливих програм, якщо ви вживали вищезазначених запобіжних заходів. Зрештою, пароль користувача вже передається у звичайному тексті під час входу (якщо ви не робите певного шифрування JavaScript у браузері), а також файли cookie для кожного запиту.

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

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

(Оновлено, щоб охопити наслідки встановлення з'єднання лише для SSL.)


3
Ви можете отримати сертифікат DSD GoDaddy за приблизно 30 доларів на рік, я думаю. Я був шокований, побачивши, на скільки коштують серти Verisign SSL (600 доларів на рік чи щось, якщо я правильно пам’ятаю?), Але варіант GoDaddy цілком здійсненний.
Брайан Армстронг

19
Якщо ви не використовуєте SSL / TLS взаємну автентифікацію, і серт, який використовується користувачем / клієнтом, довіряється сервером, ви не підтвердили автентифікацію користувача на сервері / програмі. Вам потрібно буде зробити щось більше для автентифікації користувача на сервері / програмі.
Полд

5
Райан: Шифрування SSL в ці дні займає досить невеликий об'єм процесорної потужності порівняно з тим, що ви використовуєте для отримання відповіді з такою рамкою веб-додатків, як Django або Rails тощо.
Cameron Walsh,

4
certs від startcom є безкоштовними та широко визнаними. cacert.org - це відкрита альтернатива з меншим визнанням
Діма Тиснек

17
Це не стосується питання, що стосується автентифікації.
Сем Стайнсбі

8

Або ви можете використовувати відоме рішення цієї проблеми та використовувати SSL. Сертифіковані сертифікати безкоштовні, і це особистий проект, правда?


2
Сертифіковані сертифікати безкоштовні, але AFAIK вам все-таки потрібен статичний IP.
dF.

8
@dF немає вимоги мати статичний IP, за винятком певних ліцензійних вимог комерційної оплати за сертифікати.
Кріс Марісіч

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

5

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

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


9
Створювати рядок, який генерує той самий хеш md5, як і дійсний вміст, може бути набагато простішим, ніж повинен бути, але придумати злу версію дійсного контенту, яка хеширує однакове значення, все ще надмірно складно. Ось чому md5 вже не використовується для хешей паролів, але все ще використовується для перевірки завантажень.
Тім Готьє

3

Насправді, оригінальний S3 auth дійсно дозволяє вміст підписувати, хоча і зі слабким підписом MD5. Ви можете просто застосувати їх необов'язкову практику щодо включення заголовка Content-MD5 в HMAC (рядок для підписання).

http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

Їх нова схема аутентифікації v4 більш безпечна.

http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html


1

Пам'ятайте, що ваші пропозиції ускладнюють спілкування клієнтів із сервером. Їм потрібно зрозуміти ваше інноваційне рішення та відповідно зашифрувати дані, ця модель не настільки хороша для публічного API (якщо ви не Amazon \ yahoo \ google ..).

У будь-якому випадку, якщо ви повинні зашифрувати вміст тіла, я б запропонував вам перевірити існуючі стандарти та рішення, як-от:

Шифрування XML (стандарт W3C)

Безпека XML

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