Как защитить вызовы REST API?


Я разрабатываю веб-приложение restful, которое использует некоторые популярные веб-фреймворки на бэкэнде, скажем (rails, sinatra, flask, express.js). В идеале, я хочу развивать клиентскую сторону с позвоночником.js. Как я могу позволить только моей стороне клиента javascript взаимодействовать с этими вызовами API? Я не хочу, чтобы эти вызовы API были общедоступными и вызывались curl или просто введя ссылку в браузере.

6 69

6 ответов:

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

тем не менее, если я правильно прочитал Ваш вопрос, это не то, чего вы хотите избежать: то, что вы действительно не хотите, чтобы ваш API потреблялся (на регулярной основе) без участия вашего клиента JS. Вот некоторые идеи по поводу как если не применять, то хотя бы поощрять использование вашего клиента:

  • Я уверен, что ваш API имеет какое-то поле аутентификации (например, хэш, вычисленный на клиенте). Если нет, то взгляните на это так вопрос. Убедитесь, что вы используете соль (или даже ключ API), который предоставляется Вашему клиенту JS на сессии основа (a.o.t. hardcoded). Таким образом, несанкционированный потребитель вашего API вынужден гораздо больше работать.

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

  • на стороне сервера запомните последние несколько вызовов API, и прежде чем разрешить еще один, проверьте, позволяет ли бизнес-логика для нового прямо сейчас: это лишает злоумышленника возможности концентрировать многие из его сеансы в один сеанс с вашим сервером: в сочетании с другими мерами это позволит легко обнаружить злоумышленника.

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

вы должны реализовать какую-то систему аутентификации. Один из хороших способов справиться с этим-определить некоторые ожидаемые переменные заголовка. Например, у вас может быть вызов API auth/login, который возвращает токен сеанса. Последующие вызовы вашего API будут ожидать, что токен сеанса будет установлен в переменной заголовка HTTP с определенным именем, например "your-api-token".

в качестве альтернативы многие системы создают токены доступа или ключи, которые ожидаются (например, youtube, facebook или twitter), используя некоторые своего рода система учетных записей api. В этих случаях ваш клиент должен был бы хранить их каким-то образом в клиенте.

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

теперь есть открытый стандарт под названием "JSON Web Token",

см.https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token

JSON Web Token (JWT)-это открытый стандарт на основе JSON (RFC 7519) для создание маркеров, которые утверждают некоторое количество утверждений. Например, сервер может создать маркер с утверждением " вошел в систему как администратор" и предоставить клиенту. Затем клиент может использовать этот маркер для доказать это они вошли в систему как администратор. Маркеры подписываются ключ сервера, поэтому сервер может проверить, что маркер легитимный. Маркеры предназначены, чтобы быть компактным, URL-адрес-безопасна и практична в использовании особенно в контексте единого входа (SSO) в веб-браузере. Претензии JWT могут обычно используется для передачи удостоверений аутентифицированных пользователей между поставщик удостоверений и поставщик услуг или любые другие типы утверждений в соответствии с требованиями бизнес-процессов.[1] [2] токены также могут быть проверку подлинности и зашифрованный.[3][4]

извините меня @MarkAmery и Евгений, но это неверно.

ваше приложение js+html (клиент), работающее в браузере, может быть настроено на исключение несанкционированный прямые вызовы API следующим образом:

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

перед аутентификацией вызовы API не принимаются.

во время аутентификации возвращается "токен".

после аутентификации будут приниматься только вызовы API с аутентификацией "токен".

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

  1. второй шаг: Теперь установите дополнительный API безопасности, который должен быть вызван в течение короткого периода времени после того, как клиентское приложение JS+html было первоначально запрошено с сервера. Этот "обратный вызов" сообщит серверу, что клиент был успешно загружен. Ограничьте вызовы REST API для работы только в том случае, если клиент был запрошен недавно и успешно.

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

Так что вам не придется беспокоиться, что это может быть неавторизованный пользователь без полномочий.

(название вопроса: "Как я защищаю вызовы REST API", и от большинства из того, что вы говорите, это ваша главная проблема, а не буквальный вопрос о том, как ваш API называется, а скорее кем, правильно?)

  1. установите сеанс var на сервере, когда клиент впервые загружает ваш index.html (или backbone.js etc.)

  2. проверьте этот var на стороне сервера при каждом вызове API.

P. S. Это не "решения безопасности"!!! Это просто для облегчения нагрузки на ваш сервер, чтобы люди не злоупотребляли им или "горячей ссылкой" на ваш API с других веб-сайтов и приложений.

вот что я делаю:

  1. защитите API с помощью заголовка HTTP с такими вызовами, как X-APITOKEN:

  2. использовать переменные сеанса в PHP. Имейте систему входа в систему и сохраните токен пользователя в переменных сеанса.

  3. вызовите код JS с Ajax на PHP и используйте переменную сеанса с curl для вызова API. Таким образом, если переменная сеанса не задана, она не будет вызываться, а код PHP содержит маркер доступа к API.