Changeset 7592
- Timestamp:
- 09/23/07 02:32:55 (8 months ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_controller.rb (modified) (2 diffs)
- trunk/actionpack/lib/action_controller/base.rb (modified) (1 diff)
- trunk/actionpack/lib/action_controller/request_forgery_protection.rb (added)
- trunk/actionpack/lib/action_controller/rescue.rb (modified) (1 diff)
- trunk/actionpack/lib/action_view/base.rb (modified) (1 diff)
- trunk/actionpack/lib/action_view/helpers/form_tag_helper.rb (modified) (2 diffs)
- trunk/actionpack/lib/action_view/helpers/prototype_helper.rb (modified) (1 diff)
- trunk/actionpack/lib/action_view/helpers/text_helper.rb (modified) (4 diffs)
- trunk/actionpack/lib/action_view/helpers/url_helper.rb (modified) (1 diff)
- trunk/actionpack/test/controller/request_forgery_protection_test.rb (added)
- trunk/actionpack/test/template/form_helper_test.rb (modified) (1 diff)
- trunk/actionpack/test/template/form_tag_helper_test.rb (modified) (1 diff)
- trunk/actionpack/test/template/prototype_helper_test.rb (modified) (1 diff)
- trunk/actionpack/test/template/scriptaculous_helper_test.rb (modified) (1 diff)
- trunk/actionpack/test/template/url_helper_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r7589 r7592 1 1 *SVN* 2 3 * Merge csrf_killer plugin into rails. Adds RequestForgeryProtection model that verifies session-specific _tokens for non-GET requests. [Rick] 2 4 3 5 * Secure #sanitize, #strip_tags, and #strip_links helpers against xss attacks. Closes #8877. [Rick, lifofifo, Jacques Distler] trunk/actionpack/lib/action_controller.rb
r7450 r7592 55 55 require 'action_controller/components' 56 56 require 'action_controller/record_identifier' 57 require 'action_controller/request_forgery_protection' 57 58 58 59 require 'action_view' … … 75 76 include ActionController::Components 76 77 include ActionController::RecordIdentifier 78 include ActionController::RequestForgeryProtection 77 79 end trunk/actionpack/lib/action_controller/base.rb
r7520 r7592 327 327 @@resource_action_separator = "/" 328 328 cattr_accessor :resource_action_separator 329 330 # Sets the token parameter name for RequestForgery. Calling #verify_token sets it to :_token by default 331 @@request_forgery_protection_token = nil 332 cattr_accessor :request_forgery_protection_token 329 333 330 334 # Holds the request object that's primarily used to get environment variables through access like trunk/actionpack/lib/action_controller/rescue.rb
r7438 r7592 21 21 'ActiveRecord::RecordNotSaved' => :unprocessable_entity, 22 22 'ActionController::MethodNotAllowed' => :method_not_allowed, 23 'ActionController::NotImplemented' => :not_implemented 23 'ActionController::NotImplemented' => :not_implemented, 24 'ActionController::InvalidToken' => :unprocessable_entity 24 25 } 25 26 trunk/actionpack/lib/action_view/base.rb
r7589 r7592 329 329 end 330 330 331 delegate :request_forgery_protection_token, :to => :controller 332 331 333 @@template_handlers = HashWithIndifferentAccess.new 332 334 trunk/actionpack/lib/action_view/helpers/form_tag_helper.rb
r7423 r7592 402 402 when /^post$/i, "", nil 403 403 html_options["method"] = "post" 404 ''404 request_forgery_protection_token ? content_tag(:div, token_tag, :style => 'margin:0;padding:0') : '' 405 405 else 406 406 html_options["method"] = "post" 407 content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) , :style => 'margin:0;padding:0')407 content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0') 408 408 end 409 409 end … … 420 420 concat("</form>", block.binding) 421 421 end 422 423 def token_tag 424 if request_forgery_protection_token.nil? 425 '' 426 else 427 tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_token) 428 end 429 end 422 430 end 423 431 end trunk/actionpack/lib/action_view/helpers/prototype_helper.rb
r7468 r7592 739 739 js_options['parameters'] = options[:with] 740 740 end 741 742 if request_forgery_protection_token 743 if js_options['parameters'] 744 js_options['parameters'] << " + '&" 745 else 746 js_options['parameters'] = "'" 747 end 748 js_options['parameters'] << "_token=' + encodeURIComponent('#{escape_javascript form_token}')" 749 end 741 750 742 751 options_for_javascript(js_options) trunk/actionpack/lib/action_view/helpers/text_helper.rb
r7589 r7592 326 326 # # => Blog: Visit 327 327 def strip_links(html) 328 # Stupid firefox treats '<href="http://whatever.com" onClick="alert()">something' as link!329 if html.index("<a") || html.index("<href")330 tokenizer = HTML::Tokenizer.new(html)331 result = ''332 while token = tokenizer.next333 node = HTML::Node.parse(nil, 0, 0, token, false)334 result << node.to_s unless node.is_a?(HTML::Tag) && ["a", "href"].include?(node.name)335 end 336 strip_links(result ) # Recurse - handle all dirty nested links328 if !html.blank? && html.index("<a") || html.index("<href") 329 tokenizer = HTML::Tokenizer.new(html) 330 result = returning [] do |result| 331 while token = tokenizer.next 332 node = HTML::Node.parse(nil, 0, 0, token, false) 333 result << node.to_s unless node.is_a?(HTML::Tag) && ["a", "href"].include?(node.name) 334 end 335 end 336 strip_links(result.join) # Recurse - handle all dirty nested links 337 337 else 338 338 html … … 442 442 # 443 443 # ==== Examples 444 # 444 445 # strip_tags("Strip <i>these</i> tags!") 445 446 # # => Strip these tags! … … 451 452 # # => Welcome to my website! 452 453 def strip_tags(html) 453 return html if html.blank? 454 if html.index("<") 455 text = "" 456 tokenizer = HTML::Tokenizer.new(html) 457 454 return html if html.blank? || !html.index("<") 455 tokenizer = HTML::Tokenizer.new(html) 456 457 text = returning [] do |text| 458 458 while token = tokenizer.next 459 459 node = HTML::Node.parse(nil, 0, 0, token, false) … … 461 461 text << node.to_s if node.class == HTML::Text 462 462 end 463 # strip any comments, and if they have a newline at the end (ie. line with464 # only a comment) strip that too465 strip_tags(text.gsub(/<!--(.*?)-->[\n]?/m, "")) # Recurse - handle all dirty nested tags466 else467 html # already plain text468 end463 end 464 465 # strip any comments, and if they have a newline at the end (ie. line with 466 # only a comment) strip that too 467 # Recurse - handle all dirty nested tags 468 strip_tags(text.join.gsub(/<!--(.*?)-->[\n]?/m, "")) 469 469 end 470 470 trunk/actionpack/lib/action_view/helpers/url_helper.rb
r7548 r7592 473 473 end 474 474 475 if request_forgery_protection_token 476 submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); " 477 submit_function << "s.setAttribute('name', '_token'); s.setAttribute('value', '#{escape_javascript form_token}'); f.appendChild(s);" 478 end 475 479 submit_function << "f.submit();" 476 480 end trunk/actionpack/test/template/form_helper_test.rb
r7541 r7592 712 712 "/posts/#{post.id}" 713 713 end 714 715 def request_forgery_protection_token 716 nil 717 end 714 718 end trunk/actionpack/test/template/form_tag_helper_test.rb
r7423 r7592 178 178 assert_dom_equal expected, _erbout 179 179 end 180 181 def request_forgery_protection_token 182 nil 183 184 end 180 185 end trunk/actionpack/test/template/prototype_helper_test.rb
r7468 r7592 61 61 62 62 protected 63 64 def request_forgery_protection_token 65 nil 66 end 67 63 68 def create_generator 64 69 block = Proc.new { |*args| yield *args if block_given? } trunk/actionpack/test/template/scriptaculous_helper_test.rb
r7396 r7592 90 90 drop_receiving_element("droptarget1", :accept => ['tshirts','mugs'], :update => 'infobox') 91 91 end 92 93 def request_forgery_protection_token 94 nil 95 end 92 96 end trunk/actionpack/test/template/url_helper_test.rb
r7580 r7592 268 268 assert_dom_equal "<script type=\"text/javascript\">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)") 269 269 end 270 271 def request_forgery_protection_token 272 nil 273 end 270 274 end 271 275