Рекомендации по защите REST API / веб-службы [закрыто]

829

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

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

Хотя я понимаю, что REST намеренно не имеет спецификаций, аналогичных WS- *, я надеюсь, что появились лучшие практики или рекомендуемые шаблоны.

Любое обсуждение или ссылки на соответствующие документы будут очень благодарны. Если это имеет значение, мы будем использовать WCF с сериализованными сообщениями POX / JSON для наших REST API / Services, созданных с использованием v3.5 .NET Framework.

Натан
источник
1
Знаете ли вы какое-нибудь полноценное реальное приложение, использующее хорошие шаблоны и практики с REST API и веб-сервисами в github?
PreguntonCojoneroCabrón

Ответы:

298

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

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

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

Грег Хьюгилл
источник
3
SSL является важной частью безопасности, но не все приложения требуют такого уровня шифрования. Если кто-то ворует транзитом то, что вы собираетесь опубликовать в Твиттере, это такой существенный недостаток? Для большинства API SSL шифрование будет предпочтительным. Требования к инфраструктуре SSL несколько выше, чем с открытым текстом, и никакие промежуточные (читай здесь краевые) серверы кэширования не могут участвовать в кешировании многократно доступного контента. Осторожно, ваша масштабируемость может пострадать, если вам абсолютно необходимо предлагаемое шифрование.
Норман Х
36
@NormanH: Ваш аргумент является показным, потому что если кто-то сможет увидеть всю транзакцию, которую я использую для публикации в Твиттере, то он может выдать себя за меня и опубликовать свои собственные сообщения под моим именем.
Грег Хьюгилл
3
Цитируя википедию о дайджест-проверке подлинности, «дайджест-проверка подлинности доступа является одним из согласованных методов, которые веб-сервер может использовать для согласования учетных данных с веб-браузером пользователя. Он применяет хэш-функцию к паролю перед его отправкой по сети, которая безопаснее, чем обычная аутентификация доступа, которая отправляет открытый текст. " что будет одним из стандартных способов достижения того, о чем я говорил выше. (Подробности см. В en.wikipedia.org/wiki/Digest_access_authentication )
Норман Х
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 auth over 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? Или это не зависит от формата обмена данными. Нужно руководство.
Бхаргав Джавери
72

Возможно, вы также захотите взглянуть на OAuth , новый открытый протокол для авторизации на основе токенов, специально предназначенный для http apis.

Это очень похоже на подход, принятый flickr, и помните, что apis молока "rest" (не обязательно хорошие примеры успокоительного apis, но хорошие примеры подхода, основанного на токене).

Джон Сперлок
источник
3
Но, похоже, что двуногий oAuth, который, как мне кажется, нужен здесь, не покрывается (недостатком информации) так же, как 3-х ножной.
Redben
4
OAuth - это делегирование авторизации, т.е. я владелец информации / учетной записи, позволяющей сервису A взаимодействовать с моими данными в сервисе B (например, я позволил Твиттеру писать на моем фейсбуке). Это не авторизация в более широком смысле, которая касается контроля того, что пользователи могут делать с ресурсами (данными, информацией, услугами ...). Вот где вступает XACML. XACML позволяет вам определять политики авторизации о том, кто что может делать.
Дэвид Броссар
60

На Github найден отличный контрольный список :

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

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

  • Использование Max Retryи тюрьма функции в логине.

  • Используйте шифрование на всех конфиденциальных данных.

JWT (веб-токен JSON)

  • Используйте случайный сложный ключ (JWT Secret), чтобы сделать грубое форсирование токена очень сложно.

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

  • Сделать срок действия токена ( TTL, RTTL) как можно короче.

  • Не храните конфиденциальные данные в JWTполезной нагрузке, они могут быть легко декодированы.

OAuth

  • Всегда проверяйте на redirect_uriстороне сервера, чтобы разрешить только URL из белого списка.

  • Всегда пытайтесь обменять на код, а не на токены (не разрешайте response_type=token).

  • Использование параметра состояния со случайной хэш , чтобы предотвратить CSRFна OAuthпроцесс аутентификации.

  • Определите область по умолчанию и проверьте параметры области для каждого приложения.

Доступ

  • Ограничьте количество запросов (регулирование), чтобы избежать атак DDoS / brute-force.

  • Используйте HTTPS на стороне сервера, чтобы избежать MITM (Man In the Middle Attack)

  • Используйте HSTSзаголовок с SSL, чтобы избежать атаки SSL Strip.

вход

  • Используйте правильный метод HTTP в соответствии с операцией: GET(чтение), POST(создание), PUT/PATCH(замена / обновление) и DELETE(для удаления записи) и ответьте, 405 Method Not Allowedесли запрошенный метод не подходит для запрошенного ресурса.

  • Проверьте тип содержимого по Acceptзаголовку запроса (согласование содержимого), чтобы разрешить только ваш поддерживаемый формат (например application/xml, application/jsonи т. Д.), И отвечайте 406 Not Acceptableответом, если он не совпадает.

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

  • Проверяйте пользовательский ввод, чтобы избежать распространенных уязвимостей (например, XSS, SQL-инъекция, удаленное выполнение кода и т. Д.).

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

  • Используйте службу API-шлюза для включения кэширования, Rate Limitполитик (например, Quota, Spike Arrest, Concurrent Rate Limit) и динамического развертывания ресурсов API.

обработка

  • Проверьте, все ли конечные точки защищены за аутентификацией, чтобы избежать прерывания процесса аутентификации.

  • Следует избегать использования собственного идентификатора ресурса. Используйте / me / orders вместо / user / 654321 / orders.

  • Не увеличивайте автоматически идентификаторы. Вместо этого используйте UUID.

  • Если вы анализируете XML-файлы, убедитесь, что синтаксический анализ сущностей не включен, чтобы избежать XXE (атака внешней сущности XML).

  • Если вы анализируете XML-файлы, убедитесь, что расширение сущностей не включено, чтобы избежать бомбардировки Billion Laughs / XML с помощью экспоненциальной атаки на расширение сущностей.

  • Используйте CDN для загрузки файлов.

  • Если вы имеете дело с огромным количеством данных, используйте Workers and Queues для максимально возможной обработки в фоновом режиме и быстрого возврата ответа, чтобы избежать блокировки 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: «Не используйте обычную аутентификацию Используйте стандартную аутентификацию (например, JWT, OAuth)». Вы не можете получить более стандартную, чем Basic Auth, и она имеет свое место, особенно для API, где клиенты не являются браузерами (для браузеров JWT обычно более подходит). OAuth, с другой стороны, использует целый ряд других компромиссов для аутентификации и на самом деле не сравним с Basic Auth и JWT.
Johndodo
Вы правы, BasicAuth с HTTPS является обычным явлением, но это горячо обсуждается - security.stackexchange.com/questions/988/… . Я все равно уберу эту точку.
Андрейс
43

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

stinkymatt
источник
На самом деле мы используем это для некоторых интеграций, а также для зашифрованных туннелей vpn для поддержки старых систем, которые мы не контролируем и которые не могут обмениваться данными через https.
Кейси
Клиентские сертификаты могут создавать проблемы, когда вам требуется балансировка нагрузки ... это можно сделать, но это не так просто.
Джереми Логан
2
@fiXedd - Мой опыт работы с клиентскими сертификатами был противоположным, потому что они действительно не имеют статуса. Соединения, прошедшие проверку подлинности с помощью сертификата клиента, могут быть сбалансированы по нагрузке с помощью простого балансировщика нагрузки, не принимая во внимание постоянство соединения, поскольку они требуют абсолютно нулевого общего состояния между клиентом и сервером.
stinkymatt
4
О, вы можете сделать это .... вы можете просто настроить балансировщик нагрузки для пересылки трафика TCP, но вы не можете, например, использовать балансировщик нагрузки в качестве точки завершения для SSL.
Джереми Логан
Все еще безопасно, если клиентские сертификаты и его корневые права являются самозаверяющими? Корневой центр будет импортирован в доверенные корневые центры сертификации клиента.
Джойс
38

Каждый в этих ответах упустил из виду истинный контроль доступа / авторизацию.

Если, например, ваши API-интерфейсы REST / веб-службы предназначены для публикации / получения медицинских карт, вы можете определить политику контроля доступа о том, кто может получить доступ к данным и при каких обстоятельствах. Например:

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

Для определения и реализации этих детальных авторизаций вам потребуется использовать язык управления доступом на основе атрибутов, называемый XACML, расширяемый язык разметки управления доступом.

Другие стандарты здесь для следующего:

  • OAuth: идентификатор федерация и делегирование полномочий, например, разрешение службе действовать от моего имени в другой службе (Facebook может публиковать в моем Twitter)
  • SAML: федерация идентификации / веб-служба единого входа. 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 является более сложной, менее функциональной, менее полезной, более неполной и, что наиболее важно, менее безопасной ". , Чтобы было ясно, комментарий, который я цитирую, был сделан через несколько лет после того, как вы опубликовали свой ответ.
скомиса
17

Один из лучших постов, которые я когда-либо встречал, касающийся безопасности, поскольку он касается REST, закончился на 1 RainDrop . MySpace API использует OAuth также для обеспечения безопасности, и у вас есть полный доступ к их пользовательским каналам в коде RestChess, с которым я провел много исследований. Это было demo'd на Mix, и вы можете найти пост здесь .

degnome
источник
Спасибо за ссылку (1 RainDrop) - очень интересное обсуждение безопасности в части, касающейся SOAP v REST
Натан
15

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

Натан
источник
1
Этот подход звучит подозрительно для меня. Что мешает злоумышленнику использовать маркер идентификации для маскировки клиента? HTTPS не защищает URL или заголовки в последний раз, когда я проверял ...
Gili
2
Хм ... не уверен, что ты прав насчет этого. Я считаю, что за исключением нескольких заголовков, необходимых для понимания того, какой тип шифрования требуется, все остальные заголовки шифруются.
Натан
51
Это не правильно. HTTPS защищает ВСЕ. Идет: TCP handshake ... TLS handshake ... <ENCRYPTED> GET / foo 200 OK ... teardown </ ENCRYPTED>.
Марк Ренуф
1
Обратите внимание, что вы также можете передать токен как cookie (вместо пользовательского заголовка). Это хорошо работает в браузерах, так как использует заголовок HTTP со стандартным поведением в большинстве наборов инструментов и приложений. Что касается обслуживания, куки не должны относиться к сеансу, вы можете использовать их для передачи любого токена, который вы пожелаете.
Брюс Олдерсон
11
Wayback Machine - прекрасная вещь: описание проблемы и ее решение
cjc343
14

OWASP (Open Web Application Security Project) имеет несколько шпаргалок, охватывающих все аспекты разработки веб-приложений. Этот проект является очень ценным и надежным источником информации. Что касается услуг REST, вы можете проверить это: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

WelsonJR
источник
7

Я бы порекомендовал OAuth 2/3. Вы можете найти больше информации на http://oauth.net/2/

Абхиджит Гайквад
источник
8
Не могли бы вы уточнить, почему вы бы порекомендовали версию 2, когда она остается в основном неполной? ИМХО, версия 1.0a остается солидным решением для большинства приложений.
Butifarra
6

Я много искал о безопасности restful ws, и мы также использовали токен через cookie от клиента к серверу для аутентификации запросов. Я использовал Spring Security для авторизации запросов в сервисе, потому что мне приходилось аутентифицировать и авторизовать каждый запрос на основе указанных политик безопасности, которые уже были в БД.

Париса Качуи
источник
6

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

Что касается среды .NET я не помогу, но «веб - сервисам здания с Java» (кирпич с ~ 10 авторами) сделала помощь мне много в понимании WS- * архитектуры безопасности и, в особенности, его причуда.

kravietz
источник
4

Сам REST не предлагает никаких стандартов безопасности, но такие вещи, как OAuth и SAML быстро становятся стандартами в этой области. Однако аутентификация и авторизация - это лишь малая часть того, что вам нужно учитывать. Многие из известных уязвимостей, связанных с веб-приложениями, очень сильно относятся к REST apis. Вы должны учитывать проверку ввода, взлом сеанса, неуместные сообщения об ошибках, внутренние уязвимости сотрудников и так далее. Это большая тема.

Роберт Моршель
источник
4

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

Маниш джайн
источник
3

В результате @Nathan получил простой заголовок HTTP, а некоторые из них назвали OAuth2 и клиентские SSL-сертификаты. Суть в том, что ... ваш REST API не должен обрабатывать безопасность, так как это действительно должно выходить за рамки API.

Вместо этого следует установить уровень безопасности, будь то заголовок HTTP за веб-прокси (распространенный подход, такой как SiteMinder, Zermatt или даже Apache HTTPd), или такой сложный, как OAuth 2.

Главное, чтобы запросы работали без какого-либо взаимодействия с конечным пользователем. Все, что нужно, это убедиться, что соединение с REST API аутентифицировано. В Java EE у нас есть понятие а, userPrincipalкоторое можно получить на HttpServletRequest. В дескрипторе развертывания также указывается, что шаблон URL может быть безопасным, поэтому код REST API больше не нужно проверять.

В мире WCF я бы использовал ServiceSecurityContext.Currentтекущий контекст безопасности. Вам необходимо настроить приложение так, чтобы оно требовало аутентификации.

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

Архимед Траяно
источник
3

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

java_geek
источник
2

Это было давно, но вопрос все еще актуален, хотя ответ мог бы немного измениться.

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

Express-gateway.io является более новым и также является шлюзом API.

Мэтт Баннерт
источник