mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
html_escape should escape single quotes
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content Closes #7215
This commit is contained in:
parent
c102022089
commit
b6ab441772
10 changed files with 30 additions and 30 deletions
|
@ -126,7 +126,7 @@ module RenderTemplate
|
||||||
test "rendering a template with error properly excerts the code" do
|
test "rendering a template with error properly excerts the code" do
|
||||||
get :with_error
|
get :with_error
|
||||||
assert_status 500
|
assert_status 500
|
||||||
assert_match "undefined local variable or method `idontexist'", response.body
|
assert_match "undefined local variable or method `idontexist", response.body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ class TestController < ActionController::Base
|
||||||
|
|
||||||
# :ported:
|
# :ported:
|
||||||
def render_text_hello_world_with_layout
|
def render_text_hello_world_with_layout
|
||||||
@variable_for_layout = ", I'm here!"
|
@variable_for_layout = ", I am here!"
|
||||||
render :text => "hello world", :layout => true
|
render :text => "hello world", :layout => true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -844,7 +844,7 @@ class RenderTest < ActionController::TestCase
|
||||||
# :ported:
|
# :ported:
|
||||||
def test_do_with_render_text_and_layout
|
def test_do_with_render_text_and_layout
|
||||||
get :render_text_hello_world_with_layout
|
get :render_text_hello_world_with_layout
|
||||||
assert_equal "<html>hello world, I'm here!</html>", @response.body
|
assert_equal "<html>hello world, I am here!</html>", @response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
# :ported:
|
# :ported:
|
||||||
|
|
|
@ -8,11 +8,11 @@ class ErbUtilTest < ActiveSupport::TestCase
|
||||||
define_method "test_html_escape_#{expected.gsub(/\W/, '')}" do
|
define_method "test_html_escape_#{expected.gsub(/\W/, '')}" do
|
||||||
assert_equal expected, html_escape(given)
|
assert_equal expected, html_escape(given)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
unless given == '"'
|
ERB::Util::JSON_ESCAPE.each do |given, expected|
|
||||||
define_method "test_json_escape_#{expected.gsub(/\W/, '')}" do
|
define_method "test_json_escape_#{expected.gsub(/\W/, '')}" do
|
||||||
assert_equal ERB::Util::JSON_ESCAPE[given], json_escape(given)
|
assert_equal ERB::Util::JSON_ESCAPE[given], json_escape(given)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ class ErbUtilTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_rest_in_ascii
|
def test_rest_in_ascii
|
||||||
(0..127).to_a.map {|int| int.chr }.each do |chr|
|
(0..127).to_a.map {|int| int.chr }.each do |chr|
|
||||||
next if chr.in?('&"<>')
|
next if chr.in?('&"<>\'')
|
||||||
assert_equal chr, html_escape(chr)
|
assert_equal chr, html_escape(chr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_html_escape_once
|
def test_html_escape_once
|
||||||
assert_equal '1 < 2 & 3', html_escape_once('1 < 2 & 3')
|
assert_equal '1 <>&"' 2 & 3', html_escape_once('1 <>&"\' 2 & 3')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_html_escape_once_returns_unsafe_strings_when_passed_unsafe_strings
|
def test_html_escape_once_returns_unsafe_strings_when_passed_unsafe_strings
|
||||||
|
|
|
@ -1125,7 +1125,7 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||||
|
|
||||||
def test_options_for_select_with_element_attributes
|
def test_options_for_select_with_element_attributes
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
"<option value=\"<Denmark>\" class=\"bold\"><Denmark></option>\n<option value=\"USA\" onclick=\"alert('Hello World');\">USA</option>\n<option value=\"Sweden\">Sweden</option>\n<option value=\"Germany\">Germany</option>",
|
"<option value=\"<Denmark>\" class=\"bold\"><Denmark></option>\n<option value=\"USA\" onclick=\"" + ERB::Util.html_escape("alert('Hello World');") + "\">USA</option>\n<option value=\"Sweden\">Sweden</option>\n<option value=\"Germany\">Germany</option>",
|
||||||
options_for_select([ [ "<Denmark>", { :class => 'bold' } ], [ "USA", { :onclick => "alert('Hello World');" } ], [ "Sweden" ], "Germany" ])
|
options_for_select([ [ "<Denmark>", { :class => 'bold' } ], [ "USA", { :onclick => "alert('Hello World');" } ], [ "Sweden" ], "Germany" ])
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -374,7 +374,7 @@ class FormTagHelperTest < ActionView::TestCase
|
||||||
|
|
||||||
def test_submit_tag
|
def test_submit_tag
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
%(<input name='commit' data-disable-with="Saving..." onclick="alert('hello!')" type="submit" value="Save" />),
|
%(<input name='commit' data-disable-with="Saving..." onclick=") + ERB::Util.html_escape("alert('hello!')") + %(" type="submit" value="Save" />),
|
||||||
submit_tag("Save", :onclick => "alert('hello!')", :data => { :disable_with => "Saving..." })
|
submit_tag("Save", :onclick => "alert('hello!')", :data => { :disable_with => "Saving..." })
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,7 +84,7 @@ class TestERBTemplate < ActiveSupport::TestCase
|
||||||
def test_locals
|
def test_locals
|
||||||
@template = new_template("<%= my_local %>")
|
@template = new_template("<%= my_local %>")
|
||||||
@template.locals = [:my_local]
|
@template.locals = [:my_local]
|
||||||
assert_equal "I'm a local", render(:my_local => "I'm a local")
|
assert_equal "I am a local", render(:my_local => "I am a local")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_restores_buffer
|
def test_restores_buffer
|
||||||
|
|
|
@ -107,8 +107,8 @@ class TextHelperTest < ActionView::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_truncate_with_link_options
|
def test_truncate_with_link_options
|
||||||
assert_equal "Here's a long test and I...<a href=\"#\">Continue</a>",
|
assert_equal "Here is a long test and ...<a href=\"#\">Continue</a>",
|
||||||
truncate("Here's a long test and I need a continue to read link", :length => 27) { link_to 'Continue', '#' }
|
truncate("Here is a long test and I need a continue to read link", :length => 27) { link_to 'Continue', '#' }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_truncate_should_be_html_safe
|
def test_truncate_should_be_html_safe
|
||||||
|
@ -149,8 +149,8 @@ class TextHelperTest < ActionView::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_truncate_with_block_should_escape_the_block
|
def test_truncate_with_block_should_escape_the_block
|
||||||
assert_equal "Here's a long test and I...<script>alert('foo');</script>",
|
assert_equal "Here is a long test and ...<script>" + ERB::Util.html_escape("alert('foo');") + "</script>",
|
||||||
truncate("Here's a long test and I need a continue to read link", :length => 27) { "<script>alert('foo');</script>" }
|
truncate("Here is a long test and I need a continue to read link", :length => 27) { "<script>alert('foo');</script>" }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_highlight_should_be_html_safe
|
def test_highlight_should_be_html_safe
|
||||||
|
|
|
@ -244,7 +244,7 @@ class UrlHelperTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_link_tag_with_custom_onclick
|
def test_link_tag_with_custom_onclick
|
||||||
link = link_to("Hello", "http://www.example.com", :onclick => "alert('yay!')")
|
link = link_to("Hello", "http://www.example.com", :onclick => "alert('yay!')")
|
||||||
expected = %{<a href="http://www.example.com" onclick="alert('yay!')">Hello</a>}
|
expected = %{<a href="http://www.example.com" onclick="} + ERB::Util.html_escape("alert('yay!')") + %{">Hello</a>}
|
||||||
assert_dom_equal expected, link
|
assert_dom_equal expected, link
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -254,12 +254,12 @@ class UrlHelperTest < ActiveSupport::TestCase
|
||||||
link_to("Hello", "http://www.example.com", :data => { :confirm => "Are you sure?" })
|
link_to("Hello", "http://www.example.com", :data => { :confirm => "Are you sure?" })
|
||||||
)
|
)
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
"<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure, can you?\">Hello</a>",
|
"<a href=\"http://www.example.com\" data-confirm=\"You cant possibly be sure, can you?\">Hello</a>",
|
||||||
link_to("Hello", "http://www.example.com", :data => { :confirm => "You can't possibly be sure, can you?" })
|
link_to("Hello", "http://www.example.com", :data => { :confirm => "You cant possibly be sure, can you?" })
|
||||||
)
|
)
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
"<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure,\n can you?\">Hello</a>",
|
"<a href=\"http://www.example.com\" data-confirm=\"You cant possibly be sure,\n can you?\">Hello</a>",
|
||||||
link_to("Hello", "http://www.example.com", :data => { :confirm => "You can't possibly be sure,\n can you?" })
|
link_to("Hello", "http://www.example.com", :data => { :confirm => "You cant possibly be sure,\n can you?" })
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -272,14 +272,14 @@ class UrlHelperTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
assert_deprecated ":confirm option is deprecated and will be removed from Rails 4.1. Use ':data => { :confirm => \'Text\' }' instead" do
|
assert_deprecated ":confirm option is deprecated and will be removed from Rails 4.1. Use ':data => { :confirm => \'Text\' }' instead" do
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
"<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure, can you?\">Hello</a>",
|
"<a href=\"http://www.example.com\" data-confirm=\"You cant possibly be sure, can you?\">Hello</a>",
|
||||||
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure, can you?")
|
link_to("Hello", "http://www.example.com", :confirm => "You cant possibly be sure, can you?")
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
assert_deprecated ":confirm option is deprecated and will be removed from Rails 4.1. Use ':data => { :confirm => \'Text\' }' instead" do
|
assert_deprecated ":confirm option is deprecated and will be removed from Rails 4.1. Use ':data => { :confirm => \'Text\' }' instead" do
|
||||||
assert_dom_equal(
|
assert_dom_equal(
|
||||||
"<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure,\n can you?\">Hello</a>",
|
"<a href=\"http://www.example.com\" data-confirm=\"You cant possibly be sure,\n can you?\">Hello</a>",
|
||||||
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure,\n can you?")
|
link_to("Hello", "http://www.example.com", :confirm => "You cant possibly be sure,\n can you?")
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,9 +3,9 @@ require 'active_support/core_ext/kernel/singleton_class'
|
||||||
|
|
||||||
class ERB
|
class ERB
|
||||||
module Util
|
module Util
|
||||||
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
|
||||||
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
||||||
HTML_ESCAPE_ONCE_REGEXP = /[\"><]|&(?!([a-zA-Z]+|(#\d+));)/
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
|
||||||
JSON_ESCAPE_REGEXP = /[&"><]/
|
JSON_ESCAPE_REGEXP = /[&"><]/
|
||||||
|
|
||||||
# A utility method for escaping HTML tag characters.
|
# A utility method for escaping HTML tag characters.
|
||||||
|
@ -21,7 +21,7 @@ class ERB
|
||||||
if s.html_safe?
|
if s.html_safe?
|
||||||
s
|
s
|
||||||
else
|
else
|
||||||
s.encode(s.encoding, :xml => :attr)[1...-1].html_safe
|
s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -498,8 +498,8 @@ class OutputSafetyTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "ERB::Util.html_escape should escape unsafe characters" do
|
test "ERB::Util.html_escape should escape unsafe characters" do
|
||||||
string = '<>&"'
|
string = '<>&"\''
|
||||||
expected = '<>&"'
|
expected = '<>&"''
|
||||||
assert_equal expected, ERB::Util.html_escape(string)
|
assert_equal expected, ERB::Util.html_escape(string)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue