Настройки защиты от подделки запросов Rails

пожалуйста, помогите новичку в Rails :) У меня есть вызов protect_from_forgery (который задается по умолчанию) без атрибутов в моем классе ApplicationController.

В основном вот код:

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery
  helper_method :current_user_session, :current_user
  filter_parameter_logging :password, :password_confirmation

Я предполагаю, что он должен делать следующее: он должен предотвращать любые запросы POST без правильного authenticity_token. Но когда я отправляю почтовый запрос с помощью jQuery, как показано ниже, он работает нормально (в базе данных выполняется инструкция обновления)!

$.post($(this).attr("href"), { _method: "PUT", data: { test: true } });

Я вижу в консоли, что среди отправленных параметров нет authenticity_token, но запрос по-прежнему считается действительным. Это почему?

UPD Обнаружен параметр конфигурации в config / environment / development.rb.

config.action_controller.consider_all_requests_local = true

Из-за среды DEV и локальных запросов эти почтовые запросы jQuery были в порядке.


person Vitaly    schedule 27.04.2010    source источник


Ответы (2)


В вашем коде все в порядке, пока запрос $.post($(this).attr("href"), { _method: "PUT", data: { test: true } }); выполняется из самого приложения. Если у вас было другое приложение, работающее в другом месте, например, на localhost: 3001, и вы отправили сообщение оттуда, оно не сработает. Фактически, если вы используете firefox> 3.0, у него также есть ранняя реализация кросс-сайта xhr. Например, вы можете отправить POST с любого другого сайта (но это работает при условии, что protect_from_forgery отключено!). Причина, по которой токен аутентификации не требуется для xhr, заключается в том, что межсайтовый xhr отключен. Таким образом, можно безопасно использовать xhr без предоставления токена аутентификации. Если вы попытаетесь из любого места, кроме вашего приложения, я уверен, что это вызовет исключение, запрашивающее токен аутентификации. Также у вас должен быть определен crossdomain.xml для предотвращения доступа из внешних источников.

Попробуйте сделать это: curl -X -d url_endpoint_of_your_app. Посмотрите, получите ли вы код ответа 200. Если да, то есть что-то подозрительное.

person Shripad Krishna    schedule 28.04.2010
comment
Я думаю, что этого не следует делать с localhost даже из другого приложения. Я проверю, возможно, вы правы, и это считается местным звонком без дополнительной проверки безопасности. - person Vitaly; 28.04.2010
comment
даже если вы делаете это с localhost, он работает на разных портах. Следовательно, приложения запускаются из разных доменов. Единственным решением является изменение crossdomain.xml - person Shripad Krishna; 28.04.2010
comment
Потрясающий. Я нашел настройку для DEV env, которую можно изменить, чтобы изменить это поведение. - person Vitaly; 28.04.2010
comment
Не могли бы вы также поделиться со всеми нами тем, что вы нашли? :) - person Shripad Krishna; 29.04.2010

Возможно, глупый вопрос: вы уверены, что создаете подкласс ApplicationController? Как выглядит ваша карта маршрута? А какая версия Rails (для наглядности)?

Вы проверили, что вызов из jQuery на самом деле является POST, а не GET? (Я знаю, это кажется очевидным). Rails будет выполнять защиту только для запросов, отличных от GET.

Кроме того, каков тип содержимого отправляемого запроса. Rails также будет выполнять защиту только в соответствии с документами, если это Запрос HTML / Javascript.

person davemyron    schedule 27.04.2010
comment
А собственно, глядя на источник для verify_request? (который Rails использует для проверки токена аутентичности) кажется, что если запрос - xhr, то он не обращает внимания на токен аутентификации. Может быть jQuery устанавливает для типа содержимого что-то такое, что заставляет Rails думать, что он отвечает на запрос xhr, и игнорировать отсутствие токена аутентификации? - person davemyron; 28.04.2010
comment
Спасибо за ответ! Да, я определенно наследую ApplicationController (на самом деле я создаю подкласс AdminController, который является подклассом ApplicationController). И да, это запрос POST / PUT согласно файлу development.log. Я также вижу там все параметры запроса POST и нет Authentity_token. Разве это не должно вызывать исключение даже в случае jQuery contentType по умолчанию ?! - person Vitaly; 28.04.2010
comment
Вы уверены, что если это запрос xhr, то Rails не обращает внимания на токен аутентификации? Разве это не дыра? - person Vitaly; 28.04.2010
comment
Код говорит, что он проигнорирует токен (отсутствие), если request.xhr? истинно. Если вы logger.debug request.xhr?, что там написано? Если это правда, то Rails игнорирует токен аутентификации, и вам придется поиграть с contentType. Это действительно похоже на дыру в безопасности. Чтобы исправить это здесь, вы можете отклонить любые запросы xhr. - person davemyron; 28.04.2010
comment
Честно говоря, я не думаю, что это правда: в Интернете много дискуссий о том, как добавить токен аутентификации в запрос jquery post (например, этот - brandonaaron.net/blog/2009/02/24/jquery-rails-and-ajax). А без токена не работает. Это должно быть что-то еще, может быть, из-за местного звонка, как предлагает Падди. - person Vitaly; 28.04.2010
comment
Какая версия Rails работает? Вы проверили, верно ли request.xhr?? Источник, на который я смотрел, был для v2.4, iirc, и в нем говорится, что он не будет искать токен аутентификации, если это запрос xhr. Я считаю, что это изменилось в Rails 3. - person davemyron; 28.04.2010
comment
Вот ссылка на документы / источник для verify_request? - apidock.com/rails/ActionController/RequestForgeryProtection/ - person davemyron; 28.04.2010