aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/metal/request_forgery_protection.rb
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-04-22 12:00:13 +0200
committerJosé Valim <jose.valim@gmail.com>2010-04-22 12:00:13 +0200
commit4163ccec2343ee66e2488f067eab2a15260e1219 (patch)
tree70213bd4d187c88b2fd0bbf05a54eed7ec3a49f7 /actionpack/lib/action_controller/metal/request_forgery_protection.rb
parenta8330c2006e90a6da8f621fdaf1156fa63b4049a (diff)
downloadrails-4163ccec2343ee66e2488f067eab2a15260e1219.tar.gz
rails-4163ccec2343ee66e2488f067eab2a15260e1219.tar.bz2
rails-4163ccec2343ee66e2488f067eab2a15260e1219.zip
Clean up the config object in ActionPack. Create config_accessor which just delegates to the config object, reducing the number of deprecations and add specific tests.
Diffstat (limited to 'actionpack/lib/action_controller/metal/request_forgery_protection.rb')
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb118
1 files changed, 44 insertions, 74 deletions
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 39a809657b..2ba0d6e5cd 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -4,6 +4,45 @@ module ActionController #:nodoc:
class InvalidAuthenticityToken < ActionControllerError #:nodoc:
end
+ # Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current
+ # web application, not a forged link from another site, is done by embedding a token based on a random
+ # string stored in the session (which an attacker wouldn't know) in all forms and Ajax requests generated
+ # by Rails and then verifying the authenticity of that token in the controller. Only HTML/JavaScript
+ # requests are checked, so this will not protect your XML API (presumably you'll have a different
+ # authentication scheme there anyway). Also, GET requests are not protected as these should be
+ # idempotent anyway.
+ #
+ # This is turned on with the <tt>protect_from_forgery</tt> method, which will check the token and raise an
+ # ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the
+ # error message in production by editing public/422.html. A call to this method in ApplicationController is
+ # generated by default in post-Rails 2.0 applications.
+ #
+ # The token parameter is named <tt>authenticity_token</tt> by default. If you are generating an HTML form
+ # manually (without the use of Rails' <tt>form_for</tt>, <tt>form_tag</tt> or other helpers), you have to
+ # include a hidden field named like that and set its value to what is returned by
+ # <tt>form_authenticity_token</tt>.
+ #
+ # Request forgery protection is disabled by default in test environment. If you are upgrading from Rails
+ # 1.x, add this to config/environments/test.rb:
+ #
+ # # Disable request forgery protection in test environment
+ # config.action_controller.allow_forgery_protection = false
+ #
+ # == Learn more about CSRF (Cross-Site Request Forgery) attacks
+ #
+ # Here are some resources:
+ # * http://isc.sans.org/diary.html?storyid=1750
+ # * http://en.wikipedia.org/wiki/Cross-site_request_forgery
+ #
+ # Keep in mind, this is NOT a silver-bullet, plug 'n' play, warm security blanket for your rails application.
+ # There are a few guidelines you should follow:
+ #
+ # * Keep your GET requests safe and idempotent. More reading material:
+ # * http://www.xml.com/pub/a/2002/04/24/deviant.html
+ # * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
+ # * Make sure the session cookies that Rails creates are non-persistent. Check in Firefox and look
+ # for "Expires: at end of session"
+ #
module RequestForgeryProtection
extend ActiveSupport::Concern
@@ -12,54 +51,17 @@ module ActionController #:nodoc:
included do
# Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
# sets it to <tt>:authenticity_token</tt> by default.
- config.request_forgery_protection_token ||= :authenticity_token
+ config_accessor :request_forgery_protection_token
+ self.request_forgery_protection_token ||= :authenticity_token
# Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
- config.allow_forgery_protection ||= true
+ config_accessor :allow_forgery_protection
+ self.allow_forgery_protection = true if allow_forgery_protection.nil?
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
end
- # Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current
- # web application, not a forged link from another site, is done by embedding a token based on a random
- # string stored in the session (which an attacker wouldn't know) in all forms and Ajax requests generated
- # by Rails and then verifying the authenticity of that token in the controller. Only HTML/JavaScript
- # requests are checked, so this will not protect your XML API (presumably you'll have a different
- # authentication scheme there anyway). Also, GET requests are not protected as these should be
- # idempotent anyway.
- #
- # This is turned on with the <tt>protect_from_forgery</tt> method, which will check the token and raise an
- # ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the
- # error message in production by editing public/422.html. A call to this method in ApplicationController is
- # generated by default in post-Rails 2.0 applications.
- #
- # The token parameter is named <tt>authenticity_token</tt> by default. If you are generating an HTML form
- # manually (without the use of Rails' <tt>form_for</tt>, <tt>form_tag</tt> or other helpers), you have to
- # include a hidden field named like that and set its value to what is returned by
- # <tt>form_authenticity_token</tt>.
- #
- # Request forgery protection is disabled by default in test environment. If you are upgrading from Rails
- # 1.x, add this to config/environments/test.rb:
- #
- # # Disable request forgery protection in test environment
- # config.action_controller.allow_forgery_protection = false
- #
- # == Learn more about CSRF (Cross-Site Request Forgery) attacks
- #
- # Here are some resources:
- # * http://isc.sans.org/diary.html?storyid=1750
- # * http://en.wikipedia.org/wiki/Cross-site_request_forgery
- #
- # Keep in mind, this is NOT a silver-bullet, plug 'n' play, warm security blanket for your rails application.
- # There are a few guidelines you should follow:
- #
- # * Keep your GET requests safe and idempotent. More reading material:
- # * http://www.xml.com/pub/a/2002/04/24/deviant.html
- # * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
- # * Make sure the session cookies that Rails creates are non-persistent. Check in Firefox and look
- # for "Expires: at end of session"
- #
module ClassMethods
# Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
#
@@ -79,22 +81,6 @@ module ActionController #:nodoc:
self.request_forgery_protection_token ||= :authenticity_token
before_filter :verify_authenticity_token, options
end
-
- def request_forgery_protection_token
- config.request_forgery_protection_token
- end
-
- def request_forgery_protection_token=(val)
- config.request_forgery_protection_token = val
- end
-
- def allow_forgery_protection
- config.allow_forgery_protection
- end
-
- def allow_forgery_protection=(val)
- config.allow_forgery_protection = val
- end
end
protected
@@ -104,22 +90,6 @@ module ActionController #:nodoc:
before_filter :verify_authenticity_token, options
end
- def request_forgery_protection_token
- config.request_forgery_protection_token
- end
-
- def request_forgery_protection_token=(val)
- config.request_forgery_protection_token = val
- end
-
- def allow_forgery_protection
- config.allow_forgery_protection
- end
-
- def allow_forgery_protection=(val)
- config.allow_forgery_protection = val
- end
-
# The actual before_filter that is used. Modify this to change how you handle unverified requests.
def verify_authenticity_token
verified_request? || raise(ActionController::InvalidAuthenticityToken)
@@ -146,7 +116,7 @@ module ActionController #:nodoc:
end
def protect_against_forgery?
- config.allow_forgery_protection
+ allow_forgery_protection
end
end
end