Руководство по безопасности REST API

Знание того, как защитить REST API, так же необходимо, как и написание самих API. В основном REST API основаны на протоколе HTTP, и любой пользователь, имеющий подключение к Интернету, может получить к ним доступ, а также и несанкционированные пользователи. Крайне важно писать безопасные API для защиты бизнеса.

Прежде чем приступить к защите RESTful API, давайте разберемся, какие у нас есть варианты как разработчиков. Что подойдет для нашего варианта использования?

1. Разница между аутентификацией и авторизацией

Прежде чем перейти к основному обсуждению, давайте проясним, что такое аутентификация и что такое авторизация.

Проще говоря, аутентификация — это процесс подтверждения того, что «пользователь действительно тот, за кого себя выдает». С технической точки зрения, это процесс входа в систему с помощью имени пользователя/пароля или любых подобных механизмов, например, сканирования отпечатков пальцев, токена безопасности, контрольных вопросов или токена SAML, полученного при входе в систему SSO. Должно быть что-то, что может идентифицировать пользователя среди других.

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

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

2. Четыре способа защиты RESTful веб-сервисов

Существует несколько способов защитить RESTful API в Java. Давайте рассмотрим 4 самых популярных варианта:

2.1. Базовая аутентификация

Это самый простой из всех методов и, вероятно, наиболее используемый. Вы используете формы логина/пароля — это только базовая аутентификация. Вы вводите свое имя пользователя и пароль и отправляете форму на сервер, и приложение идентифицирует вас как пользователя — вам разрешено использовать систему — в противном случае вы получаете ошибку.

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

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

2.2. Аутентификация DIGEST

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

Подробнее: Генерация зашифрованных паролей

В Java также существует множество подобных алгоритмов хеширования, которые могут оказаться действительно эффективными для защиты паролей, например, алгоритмы MD5, SHA, BCrypt, SCrypt и PBKDF2WithHmacSHA1.

Пожалуйста, помните, что как только этот хэш пароля сгенерирован и сохранен в базе данных, вы не сможете преобразовать его обратно в исходный пароль. Каждый раз, когда пользователь входит в приложение, вам придется заново генерировать хэш пароля и сопоставлять его с хешем, сохраненным в базе данных. Таким образом, если пользователь забыл свой пароль, вам придется отправить ему временный пароль и попросить его сменить его на новый пароль. Что ж, это обычная тенденция в наши дни.

2.3. Аутентификация клиента CERT

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

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

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

Полное руководство по созданию сертификата безопасности можно найти в официальной документации Oracle.

2.4.OAuth2

Если вы когда-либо разрабатывали приложения, которые взаимодействуют друг с другом через облако, например, интеграция Facebook или аутентификация Twitter и т. д., то вы уже использовали это. Они требуют, чтобы вы предоставили ключ API и секрет API, чтобы правильно идентифицировать вас. Эти ключи API и секреты представляют собой некоторую случайную закодированную строку, которую невозможно угадать.

Чтобы понять, как это работает, предположим, что вы используете Flickr(приложение для обмена фотографиями) и хотите опубликовать некоторые из своих фотографий с помощью его REST API. Вы создаете запрос, как описано в документации Flickr, а затем отправляете его.

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

Как вы заметите, таким образом вы можете легко создавать приложения, используя API провайдера. Также провайдер позволит вам аутентифицироваться и получать доступ к публичной информации.

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

3. Реализации безопасности REST API

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

3.1.Контекст безопасности

Интерфейс javax.ws.rs.core.SecurityContext обеспечивает доступ к информации, связанной с безопасностью, для запроса и очень похож на javax.servlet.http.HttpServletRequest.

Доступ к SecurityContext осуществляется путем внедрения экземпляра в поле класса, метод установки или параметр метода с помощью аннотации javax.ws.rs.core.Context, например, в приведенном ниже коде sc.isUserInRole() используется для проверки авторизации пользователя.

@GET@Produces("text/plain;charset=UTF-8")@Path("/hello")public String sayHello(@Context SecurityContext sc) {if(sc.isUserInRole("admin"))return "Hello World!";throw new SecurityException("User is unauthorized.");}

3.2 Авторизация на уровне метода

Этот метод широко используется в корпоративных приложениях и применяется для проверки ролей и обязанностей аутентифицированного пользователя — для любой конкретной операции. JAX-RS предоставляет следующие аннотации для этой цели.

Примером использования аннотации может быть:

@RolesAllowed("ADMIN")@PUT@Path("/users/{id}")public Response updateUserById(@PathParam("id") int id) {UserDatabase.updateUser(id);return Response.status(200).build();}

Подробнее: Пример аутентификации и авторизации JAX-RS

4. Лучшие практики безопасности REST API

Давайте отметим некоторые важные моменты при проектировании безопасности ваших веб-сервисов RESTful.

  • Используйте только протокол HTTPS, чтобы все ваше общение всегда было зашифровано.
  • Никогда не отправляйте учетные данные аутентификации или ключи API в качестве параметра запроса. Они отображаются в URL и могут быть легко зарегистрированы или отслежены.
  • Всегда используйте самый сложный уровень шифрования. Это поможет обрести больше уверенности.
  • Для ресурсов, предоставляемых веб-службами RESTful, крайне важно обеспечить защиту любых запросов PUT, POST и DELETE от подделки межсайтовых запросов.
  • Всегда проверяйте входные данные как можно быстрее, как только они получены в серверном методе. Используйте только примитивные данные в качестве входного параметра, насколько это возможно.
  • Положитесь на предоставляемые фреймворком функции проверки, поскольку они уже протестированы большим сообществом.

Поделитесь своими мыслями и опытом по обеспечению безопасности веб-сервисов RESTful в вашей организации.

Прокрутить вверх