Лучшие практики для защиты REST API / веб-службы

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

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

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

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

Ответов (18)

Решение

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

Преимущество HTTP Basic в том, что его поддерживают практически все библиотеки HTTP. В этом случае вам, конечно же, потребуется SSL, потому что отправка паролей в открытом виде по сети почти всегда является плохой вещью. Базовый вариант предпочтительнее дайджеста при использовании SSL, потому что даже если вызывающий абонент уже знает, что требуются учетные данные, дайджест требует дополнительного двустороннего обращения для обмена значением nonce. При использовании Basic вызывающие абоненты просто отправляют учетные данные в первый раз.

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

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

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

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

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

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

Все в этих ответах упустили из виду настоящий контроль / авторизацию доступа.

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

  • врачи могут ПОЛУЧИТЬ медицинскую карту пациента, с которым они связаны
  • никто не может ОТПРАВИТЬ медицинские данные в нерабочее время (например, с 9 до 5)
  • конечные пользователи могут ПОЛУЧАТЬ медицинские записи, которыми они владеют, или медицинские записи пациентов, для которых они являются опекунами
  • медсестры могут ОБНОВЛЯТЬ медицинскую карту пациента, который принадлежит к тому же отделению, что и медсестра.

Чтобы определить и реализовать эти детальные авторизации, вам нужно будет использовать язык управления доступом на основе атрибутов под названием XACML, eXtensible Access Control Markup Language.

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

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

XACML не зависит от технологий. Его можно применять к Java-приложениям, .NET, Python, Ruby ... веб-службам, REST API и многому другому.

Следующие интересные ресурсы:

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

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

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

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

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

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

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

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

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

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

Прошло некоторое время, но вопрос все еще актуален, хотя ответ, возможно, немного изменился.

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

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

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

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

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

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

  • Max RetryФункции использования и заключения в тюрьму в Login.

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

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

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

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

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

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

OAuth

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

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

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

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

Доступ

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

  • Используйте 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-инъекция, удаленное выполнение кода и т. Д.).

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

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

Обработка

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

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

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

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

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

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

  • Если вы имеете дело с огромным объемом данных, используйте Workers и 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и т.д.).

Для REST нет других стандартов, кроме HTTP. Существуют установленные службы REST. Я предлагаю вам взглянуть на них и почувствовать, как они работают.

Например, при разработке собственных идей мы позаимствовали множество идей из сервиса Amazon S3 REST. Но мы решили не использовать более продвинутую модель безопасности, основанную на подписях запросов. Более простой подход - это HTTP-аутентификация через SSL. Вы должны решить, что лучше всего работает в вашей ситуации.

Кроме того, я настоятельно рекомендую книгу RESTful Web Services от Орейли. В нем объясняются основные концепции и даются некоторые передовые практики. Обычно вы можете взять модель, которую они предоставляют, и сопоставить ее со своим собственным приложением.

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

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

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

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