Найкращі практики забезпечення API / веб-сервісу REST [закрито]


828

При розробці API або послуги REST чи існують якісь встановлені найкращі практики по роботі із безпекою (автентифікація, авторизація, управління ідентичністю)?

При створенні SOAP API у вас є WS-Security як посібник, і багато літератури існує по цій темі. Я знайшов менше інформації щодо забезпечення кінцевих точок REST.

Хоча я розумію, що REST навмисно не має специфікацій, аналогічних WS- *, сподіваюся, що з’явилися кращі практики або рекомендовані зразки.

Буде дуже вдячна будь-яка дискусія чи посилання на відповідні документи. Якщо це має значення, ми би використовували WCF з серіалізованими повідомленнями POX / JSON для наших REST API / служб, побудованих за допомогою v3.5 .NET Framework.


1
чи знаєте ви будь-яке повне реальне додаток, що використовує хороші зразки та практики з API REST та веб-сервісами в github?
PreguntonCojoneroCabrón

Відповіді:


298

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

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

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


3
SSL є важливою частиною безпеки, але не всі програми вимагають такого рівня шифрування. Якщо хтось викраде транзит, що ви збираєтесь публічно публікувати у Twitter, це такий вагомий недолік? Для більшості API шифрування SSL буде кращим. Вимоги до інфраструктури SSL дещо вищі, ніж у простому тексті, і жодні проміжні (читайте тут крайові) кешування-сервери не можуть брати участь у кешуванні контенту, що отримує багато разів доступ. Остерігайтеся, ваша масштабованість може постраждати, якщо ви абсолютно вимагаєте запропонованого шифрування.
Норман Н

36
@NormanH: Ваш аргумент є сумлінним, тому що якщо хтось може побачити всю транзакцію, яку я використовую для публікації у Twitter, то він міг би себе видати за себе і розмістити власні повідомлення під моїм іменем.
Грег Х'югілл

3
Цитуючи з Вікіпедії про Дайджест автентифікації, "Перевірка автентичності доступу - це один із узгоджених методів, який веб-сервер може використовувати для узгодження облікових даних з веб-браузером користувача. Він застосовує хеш-функцію до пароля перед відправкою по мережі, що є безпечніше, ніж базова автентифікація доступу, яка надсилає простий текст ". що було б одним із стандартних способів здійснення того, про що я нагадав вище. (Дивіться en.wikipedia.org/wiki/Digest_access_authentication для деталей)
Norman H

5
"sending plaintext passwords over the net is almost universally a bad thing"- Чи можете ви детальніше зупинитися на «майже»? Коли це не погана ідея?
toniedzwiedz

2
@GregHewgill навіть у приватній мережі я не хотів би, щоб мої користувачі могли перехоплювати паролі один одного. Єдина ситуація, про яку я можу подумати, і в якій нормально надсилати пароль через мережу, - це коли користувач один у мережі. Той факт, що подібні речі трапляються в інших місцях, навряд чи є причиною цього дозволити.
toniedzwiedz

115

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

Наприклад, ми запозичили багато ідей у ​​сервісу Amazon S3 REST при розробці власного. Але ми вирішили не використовувати більш просунуту модель безпеки, засновану на підписах запиту. Найпростіший підхід - це авторизація HTTP Basic через SSL. Ви повинні вирішити, що найкраще працює у вашій ситуації.

Також настійно рекомендую книгу RESTful Web Services від O'reilly. Він пояснює основні концепції та дає деякі найкращі практики. Зазвичай ви можете взяти модель, яку вони надають, і віднести її до власної програми.


6
RESTful Web Services - це, безумовно, чудова книга. Потрібно прочитати в цій області. Це було прямо натхненно.
EdgarVerona

6
Як це так, що @aehlke отримав так багато відгуків за цей коментар, враховуючи, що (1) немає такого поняття, як специфікація REST та (2) Дисертація по польових даних про архітектурні стилі та дизайн мережевої архітектури програмного забезпечення прямо згадує REST і HTTP в 6.3: REST Застосовується до HTTP.

20
HTTP не є вимогою до REST.
nategood

1
Книга RESTful Web Services доступна безкоштовно на їхньому веб-сайті: crummy.com/writing/RESTful-Web-Services
icc97

Я планував прочитати книгу, і тоді зрозумів, що вона орієнтована переважно на формат XML. Чи варто користуватися цією книгою, враховуючи популярність JSON? Або це не залежить від формату обміну даними. Потрібні вказівки.
Bhargav Jhaveri

72

Ви також можете ознайомитися з OAuth , відкритим протоколом для авторизації на основі токенів, спеціально орієнтованого на http apis.

Він дуже схожий на підхід, який застосовують Flickr і пам'ятає молочний "відпочинок" апіс (не обов'язково хороші приклади спокійного апісу, але хороші приклади підходу на основі лексеми).


3
Але здається, що 2-ніжний oAuth, який, на мою думку, є необхідним тут, не охоплений (відсутність інформації) настільки ж, як і триногий.
redben

4
OAuth - це делегування дозволу, тобто я, власник інформації / облікового запису, нехай сервіс A взаємодіє з моїми даними про сервіс B (наприклад, я дозволяю Twitter писати у своєму facebook). Це не авторизація в більш широкому розумінні, що стосується контролю того, що користувачі можуть робити на ресурсах (дані, інформація, послуги ...). Тут відбувається крок XACML. XACML дозволяє визначити політику авторизації щодо того, хто може робити.
Девід Броссар

60

У Github знайдений чудовий контрольний список :

Аутентифікація

  • Не винаходити колесо в аутентифікації, генерації токенів, зберіганні паролів. Використовуйте стандарти.

  • Використання Max Retryта в'язниця функції входу.

  • Використовуйте шифрування на всіх конфіденційних даних.

JWT (веб-маркер JSON)

  • Використовуйте випадкову складну клавішу (JWT Secret), щоб зробити грубе примушування жетона дуже важким.

  • Не витягуйте алгоритм із корисного навантаження. Запустіть алгоритм у складі сервера (HS256 або RS256).

  • Зробіть термін дії маркера ( TTL, RTTL) якомога коротшим.

  • Не зберігайте конфіденційні дані у JWTкорисному навантаженні, їх можна легко розшифрувати.

OAuth

  • Завжди перевіряйте redirect_uriсторону сервера, щоб дозволити лише URL-адреси, що містяться в білому списку.

  • Завжди намагайтеся обмінювати код, а не жетони (не дозволяти response_type=token).

  • Використання параметра стану з випадковою хеш , щоб запобігти CSRFна OAuthпроцес аутентифікації.

  • Визначте область за замовчуванням та підтвердіть параметри області для кожної програми.

Доступ

  • Обмежте запити (Throttling), щоб уникнути DDoS / грубої атаки.

  • Використовуйте HTTPS на стороні сервера, щоб уникнути MITM (Man In The Middle Attack)

  • Використовуйте HSTSзаголовок із SSL, щоб уникнути нападу SSL Strip.

Вхідні дані

  • Використовуйте належний метод HTTP відповідно до операції: GET(прочитати), POST(створити), PUT/PATCH(замінити / оновити) та DELETE(видалити запис) та відповісти, 405 Method Not Allowedякщо запитуваний метод не підходить для запитуваного ресурсу.

  • Підтвердити тип контенту за запитом Acceptзаголовка (Content Negotiation) , щоб тільки ваш підтримуваний формат (наприклад application/xml, application/jsonі т.д.) і реагувати з 406 Not Acceptableвідповіддю , а то й відповідає.

  • Validate content-typeз розміщені дані , як ви приймаєте (наприклад application/x-www-form-urlencoded, multipart/form-data, application/jsonі т.д.).

  • Перевірте введення користувача, щоб уникнути поширених уразливих ситуацій (наприклад, XSS, SQL-ін'єкція, віддалене виконання коду тощо).

  • Не використовуйте в URL-адресі жодних конфіденційних даних (облікові дані, паролі, маркери безпеки чи ключі API), а використовуйте стандартний Authorizationзаголовок.

  • Використовуйте послугу шлюзу API, щоб увімкнути кешування, Rate Limitполітику (наприклад, квота, арешт Spike, обмеження одночасної швидкості) та динамічно розгорнути ресурси API.

Обробка

  • Перевірте, чи захищені всі кінцеві точки за аутентифікацією, щоб уникнути порушеного процесу аутентифікації.

  • Слід уникати ідентифікатора власного ресурсу користувача. Використовуйте / мені / замовлення замість / користувача / 654321 / замовлення.

  • Не здійснюйте автоматичне збільшення ідентифікаторів. Натомість використовуйте UUID.

  • Якщо ви аналізуєте файли XML, переконайтеся, що розбір об'єктів не включений, щоб уникнути XXE (атаки зовнішньої сутності XML).

  • Якщо ви аналізуєте XML-файли, переконайтеся, що розширення сутності не ввімкнено, щоб уникнути бомби Billing Laughs / XML через експоненціальну атаку розширення сутності.

  • Використовуйте CDN для завантаження файлів.

  • Якщо ви маєте справу з величезною кількістю даних, використовуйте «Робочі та черги», щоб обробити якомога більше у фоновому режимі та швидко відповідати, щоб уникнути блокування HTTP.

  • Не забудьте вимкнути режим DEBUG .

Вихідні дані

  • Надіслати X-Content-Type-Options: nosniffзаголовок.

  • Надіслати X-Frame-Options: denyзаголовок.

  • Надіслати Content-Security-Policy: default-src 'none'заголовок.

  • Видалити дактилоскопії заголовки - X-Powered-By, Server, і X-AspNet-Versionт.д.

  • Примушуйте content-typeвідповісти, якщо ви повернетесь, application/jsonтоді ваш тип вмісту відповіді є application/json.

  • Не повертайте конфіденційні дані, такі як облікові дані, паролі, маркери безпеки.

  • Поверніть належний код статусу відповідно до завершеної операції. (Наприклад 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowedі т.д.).


1
Хороший список, хоч і трохи суперечливий - і він починається з нісенітниці imho: "Не використовуйте Basic Auth Використовуйте стандартну автентифікацію (наприклад, JWT, OAuth)." Ви не можете отримати більше стандартних y ніж Basic Auth, і це має своє місце, особливо для API, де клієнти не є браузерами (для браузерів JWT зазвичай більше підходить). З іншого боку, OAuth використовує цілий інший набір компромісів для аутентифікації і насправді не можна порівняти з Basic Auth та JWT.
johndodo

Ви маєте рацію, BasicAuth з HTTPS є загальним явищем, але на ньому гостро обговорюється - security.stackexchange.com/questions/988/… . Я все одно приберу цю точку.
Андрейс

43

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


Ми фактично використовуємо це для деяких інтеграцій, а також для зашифрованих тунелів vpn для підтримки старих систем, які ми не контролюємо і не можемо спілкуватися через https.
Кейсі

Клієнтські серти можуть створити проблеми, коли потрібно балансувати навантаження ... це можна зробити, але це менш прямолінійно.
Джеремі Логан

2
@fiXedd - навпаки, мій досвід роботи з клієнтськими сертифікатами, оскільки вони справді без громадянства. Підключення, підтверджені автентичністю клієнта, можуть бути збалансовані навантаженням з німим балансиром навантаження, не зважаючи на липкість з'єднання, оскільки вони вимагають абсолютно нульового загального стану між клієнтом і сервером.
stinkymatt

4
О, ви можете це зробити .... ви можете просто перевести балансир навантаження вперед TCP-трафіку, але ви не можете, наприклад, балансира навантаження бути точкою завершення для SSL.
Джеремі Логан

Чи все-таки безпечно, якщо сертифікати клієнта та його кореневі повноваження підписуються самостійно? Кореневий авторитет буде імпортований у довірені органи кореневого сертифіката клієнта.
Джойс

38

Усі в цих відповідях не помітили справжнього контролю доступу / авторизації.

Якщо, наприклад, ваші API / веб-сервіси REST стосуються POSTing / GETing медичних записів, ви можете визначити, хто може отримати доступ до даних та за яких обставин. Наприклад:

  • лікарі можуть отримати медичну карту пацієнта, з яким вони мають догляд
  • ніхто не може розміщувати медичні дані поза робочим часом (наприклад, 9 до 5)
  • кінцеві користувачі можуть отримати медичну документацію, яка їм належить, або медичну документацію пацієнтів, для яких вона є опікуном
  • медсестри можуть ОНОВЛЮВАТИ медичну документацію пацієнта, що належить до тієї ж одиниці, що і медсестра.

Для того, щоб визначити та реалізувати ці тонкодоступні авторизації, вам потрібно буде використовувати мову управління доступом на основі атрибутів, що називається XACML, мовою розмітки eXtensible Control Access.

Інші стандарти тут:

  • OAuth: ід. федерація та делегування дозволу, наприклад, надання дозволу службі діяти від мого імені на іншій службі (Facebook може публікувати в моєму Twitter)
  • SAML: федерація ідентичності / веб-SSO. SAML дуже багато стосується того, хто такий користувач.
  • Стандарти WS-Security / WS- *: вони зосереджені на спілкуванні між службами SOAP. Вони характерні для формату повідомлень на рівні додатків (SOAP), і вони стосуються аспектів обміну повідомленнями, наприклад надійності, безпеки, конфіденційності, цілісності, атомності, подій ... Жоден контроль доступу не охоплює, і всі вони специфічні для SOAP.

XACML є технологічно-агностичним. Його можна застосувати до програм Java, .NET, Python, Ruby ..., веб-сервісів, API REST тощо.

Наступні цікаві ресурси:


2
Я не розумію, чому ви не можете просто реалізувати токен-систему, яка отримає користувача та його дозволи, які по суті будуть тим самим?
Стен

Ви можете скористатися підходом на лексемах. Це також добре працює, але вам все одно потрібна логіка, яка визначає, які дозволи отримують користувачі, іншими словами, які дозволи додати до маркера. Ось що може допомогти вам досягти XACML. Це також дозволяє уникнути набряку токенів.
Девід Броссар

2
Що стосується побічного коментаря, що "9 до 5" сприяє безпеці? Наче нападники активні лише вночі? Не кажучи про серйозні наслідки використання, як ніби лікарі працюють лише "9 на 5".
Роланд

Це загальна вимога в сценаріях охорони здоров'я. Ознайомтеся, наприклад, з HL7. Існують і сценарії розбиття скла, якщо лікарю потрібен доступ упродовж години. Що стосується хакерів, то коли вони всі ставки будуть вимкнені
Девід Броссар

1
Деякі мої колеги це справді розслідують. Дякую @SimplyG
Девід Броссар

25

Я кілька разів використовував OAuth, а також використовував деякі інші методи (BASIC / DIGEST). Я від усієї душі пропоную OAuth. Наступне посилання - найкращий підручник, який я бачив із використанням OAuth:

http://hueniverse.com/oauth/guide/


Хоча це дуже стара відповідь, що стосується OAuth 1.0, варто зазначити, що автор посилання, яке ви цитуєте, мав це сказати про OAuth 2.0 : "Я дійшов висновку, що OAuth 2.0 - це поганий протокол ... У порівнянні з OAuth 1.0, специфікація 2.0 є більш складною, менш сумісною, менш корисною, більш неповною, а головне, менш безпечною ". . Щоб було зрозуміло, коментар, який я цитую, був зроблений через кілька років після того, як ви опублікували свою відповідь.
skomisa

17

Один з найкращих дописів, які я коли-небудь зустрічав щодо безпеки, оскільки це стосується REST, закінчився на 1 RainDrop . MySpace API використовує OAuth також для безпеки, і ви маєте повний доступ до їх власних каналів у коді RestChess, з яким я багато досліджував. Це було демо в Mix, і ви можете знайти публікацію тут .


Дякуємо за посилання (1 RainDrop) - дуже цікаве обговорення безпеки, оскільки це стосується SOAP v REST
Натан

15

Дякую за відмінні поради. Ми в кінцевому підсумку скористалися користувальницьким заголовком HTTP для передачі маркера ідентичності від клієнта до сервісу, готуючись до інтеграції нашого RESTful API з майбутнім фреймворком Zermatt Identity від Microsoft. Я описав проблему тут і наше рішення тут . Я також взяв поради щодо настроювання і придбав RESTful Web Services - дуже хорошу книгу, якщо ви будуєте API RESTful будь-якого типу.


1
Такий підхід для мене звучить риба. Що заважає зловмиснику використовувати маркер ідентичності для маскування клієнта? HTTPS не захищає URL чи заголовки востаннє, коли я перевіряв ...
Gili

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

51
Це неправильно. HTTPS захищає ВСЕ. Це стосується: рукостискання TCP ... рукостискання TLS ... <ENCRYPTED> GET / foo 200 OK ... teardown </ENCRYPTED>.
Марк Ренуф

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

11
Машина Wayback - прекрасна річ: опис проблеми та рішення
cjc343

14

У OWASP (Open Web Security Security Project) є декілька чіт-листів, що висвітлюють усі аспекти розробки веб-додатків. Цей Проект є дуже цінним та надійним джерелом інформації. Щодо послуг REST, ви можете перевірити це: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet


7

Я б рекомендував OAuth 2/3. Додаткову інформацію можна знайти на http://oauth.net/2/


8
Потрібно розробити, чому ви б рекомендували версію 2, коли вона залишається значною мірою незавершеною? IMHO, версія 1.0a залишається надійним рішенням для більшості програм.
Butifarra

6

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


6

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

Що стосується середовища .NET я не допоможу, але «веб - сервісів будівлі з Java» (цегла з ~ 10 авторами) зробила допомогу мені багато в розумінні WS- * архітектури безпеки і, в особливості, його примха.


4

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


4

Я хочу додати (відповідно до stinkeymatt), найпростішим рішенням було б додати SSL сертифікати на ваш сайт. Іншими словами, переконайтеся, що вашим URL-адресом є HTTPS: //. Це покриє вашу транспортну безпеку (вибух за долар). За допомогою RESTful URL-адрес ідея полягає в тому, щоб він був простим (на відміну від WS * security / SAML), ви можете використовувати oAuth2 / openID connect або навіть Basic Auth (у простих випадках). Але вам все одно знадобиться SSL / HTTPS. Перевірте безпеку веб-API 2 ASP.NET тут: http://www.asp.net/web-api/overview/security (статті та відео)


3

Коли @Nathan виявився простим заголовком HTTP, а деякі сказали OAuth2 та SSL сертифікати на стороні клієнта. Суть у цьому полягає в тому, що ... ваш REST API не повинен обробляти безпеку, оскільки це дійсно повинно бути поза межами API.

Натомість слід забезпечити рівень безпеки, будь то HTTP Header за веб-проксі (поширений підхід, такий як SiteMinder, Zermatt або навіть Apache HTTPd), або такий складний, як OAuth 2.

Найголовніше - запити повинні працювати без будь-якої взаємодії з кінцевим користувачем. Все, що потрібно, - це гарантувати автентифікацію з'єднання з API REST. У Java EE у нас є поняття a, userPrincipalяке можна отримати на HttpServletRequest. У дескрипторі розгортання також керується тим, що шаблон URL-адреси може бути захищеним, тому код REST API більше не потрібно перевіряти.

У світі WCF я би використовував, ServiceSecurityContext.Currentщоб отримати сучасний контекст безпеки. Вам потрібно налаштувати додаток, щоб вимагати автентифікації.

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


3

Для забезпечення безпеки веб-додатків вам слід ознайомитися з OWASP ( https://www.owasp.org/index.php/Main_Page ), який надає шпаргалки для різних атак безпеки. Ви можете встановити якомога більше заходів для захисту своєї заявки. Що стосується безпеки API (авторизація, автентифікація, управління ідентичністю), існує кілька способів, як уже згадувалося (Basic, Digest та OAuth). У OAuth1.0 є отвори в петлі, тому ви можете використовувати OAuth1.0a (OAuth2.0 широко не прийнятий через проблеми з технічними умовами)


2

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

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

Express-gateway.io є останнім часом і є також шлюзом API.

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