Подтвердить что ты не робот

Rails 4 пропускает защиту_from_forgery для действий API

Я внедряю приложение Rails 4 с API. Я хочу иметь возможность вызывать API с мобильных телефонов и сам webapp. Я встретил эту заметку, исследуя protect_from_forgery:

Важно помнить, что запросы XML или JSON также затронуты, и если вы создаете API, вам понадобится что-то вроде:

class ApplicationController < ActionController::Base
  protect_from_forgery
  skip_before_action :verify_authenticity_token, if: :json_request?

  protected

  def json_request?
    request.format.json?
  end
end

Я думал об этом, но у меня есть некоторые оговорки/вопросы:

  • Это решение, похоже, закрывает отверстие CSRF, потому что теперь злоумышленник может создать ссылку с javascript onclick, который помещает JSON?
  • Будет ли проверка маркера API разумной заменой? то есть, если вместо того, чтобы пропустить проверку подлинности, разрешить ей сбой проверки и восстановления в handle_unverified_request, если токен api присутствует и исправлен для текущего пользователя?
  • Или, может быть, я должен просто сделать webapp и мобильные устройства отправить токен CSRF в заголовках HTTP? Это безопасно? Как мобильный телефон даже получит токен CSRF, учитывая, что он не передает HTML-формы?

Изменить для пояснения:

Я больше беспокоюсь о том, что пользователь webapp нажал на созданную ссылку CSRF. Мобильные пользователи аутентифицированы, авторизованы, имеют ключ API, поэтому я не беспокоюсь о них. Но, включив защиту CSRF для пользователей Webapp, мобильные пользователи заблокированы от использования защищенного API. Я хочу знать правильную стратегию для этого, и я не верю, что документация Rails дает правильный ответ.

4b9b3361

Ответ 1

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

Предоставление пользователям API отправки CSRF на самом деле не является тем, что делает CSRF. Для этого вам нужно будет внедрить тип механизма детонации, когда ваш клиент сначала попадает в конечную точку авторизации, чтобы получить код (aka CSRF), а затем отправить его в POST. это отстой для мобильных клиентов, потому что он использует свою полосу пропускания, мощность и лагги.

И вообще, действительно ли это подделка (т.е. F в CSRF), если ее авторизованный клиент ударил ваш контроллер в конце концов?

Ответ 2

Отправка маркера CSRF в HTTP-заголовке - действительно общий подход. Это гарантирует, что клиент каким-то образом получил действительный токен. Например, созданная ссылка CSRF будет отправлена ​​с помощью файлов cookie с учетными данными, но заголовок не будет включать токен CSRF. Ваш собственный javascript на клиенте будет иметь доступ к куки домена и сможет копировать токен из файла cookie в заголовок во всех запросах XHR.

AngularJS следует этому подходу, как описано здесь.

Что касается ваших первых двух вопросов:

  • Это решение, похоже, открыло отверстие CSRF...

В самом деле, поэтому вы не должны отключать токен CSRF и в вашем API.

  1. Будет ли проверка маркера API разумной заменой?...

Наверное, нет. Примите во внимание следующее (из OWASP):

Точки CSRF в запросах GET потенциально протекают в нескольких местах: история браузера, файлы журнала HTTP, сетевые устройства, которые делают ставку на запись первой строки HTTP-запроса, и заголовки Referer, если защищенный сайт ссылается на внешний сайт.

Общая рекомендация. Не пытайтесь изобрести колесо. OWASP имеет страницу под названием REST Security Cheat Sheet, а также ту, с которой я связан ранее. Вы можете следовать подходом Angular (копирование маркера из файла cookie в заголовок для каждого запроса XHR) и для регулярных форм без аякса, обязательно используйте только POST и скрытое поле, как это обычно делается в CSRF-защите статических серверных форм.