xss_shield 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/
data/README.rdoc CHANGED
@@ -14,7 +14,7 @@ will return a +SafeString+:
14
14
  and not a plain, unsafe +String+:
15
15
  <a href="/foo">A & B</a>
16
16
 
17
- This version has been tested to work with <b><i>Rails 2.1.2</i></b>. Your milage
17
+ This version has been tested to work with <b><i>Rails 2.3.4</i></b>. Your milage
18
18
  may vary.
19
19
 
20
20
  DISCLAIMER: Note that while no effort is spared to ensure that this plugin works as
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 2.0.0
@@ -1,6 +1,6 @@
1
1
  # Create our own ERB compiler to handle <%= %> differently.
2
- # See /usr/lib/ruby/1.8/erb.erb.
3
- class XSSProtectedERB < ERB
2
+ # See /usr/lib64/ruby/1.8/erb.rb.
3
+ class XssShieldERB < ERB
4
4
  class Compiler < ::ERB::Compiler
5
5
  def compile(s)
6
6
  out = Buffer.new(self)
@@ -78,7 +78,7 @@ class XSSProtectedERB < ERB
78
78
  @safe_level = safe_level
79
79
  # NOTE: Changed lines
80
80
 
81
- compiler = XSSProtectedERB::Compiler.new(trim_mode)
81
+ compiler = XssShieldERB::Compiler.new(trim_mode)
82
82
 
83
83
  # NOTE: End changed lines
84
84
  set_eoutvar(compiler, eoutvar)
@@ -88,14 +88,22 @@ class XSSProtectedERB < ERB
88
88
  end
89
89
 
90
90
  # Use our own ERB handler.
91
- # See /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_view/template_handlers/erb.rb.
91
+ # See /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.4/lib/action_view/template_handlers/erb.rb.
92
92
  module ActionView
93
93
  module TemplateHandlers
94
- class ERB < TemplateHandler
94
+ class XssShieldERB < TemplateHandler
95
+ include Compilable
96
+
97
+ cattr_accessor :erb_trim_mode
98
+ self.erb_trim_mode = '-'
99
+
95
100
  def compile(template)
96
- ::XSSProtectedERB.new(template.source, nil, @view.erb_trim_mode).src
101
+ ::XssShieldERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
97
102
  end
98
103
  end
99
104
  end
100
105
  end
101
106
 
107
+ ActionView::Template.register_default_template_handler(
108
+ :erb, ActionView::TemplateHandlers::XssShieldERB)
109
+
@@ -55,11 +55,9 @@ class ActionView::Base
55
55
  mark_methods_as_xss_safe :select,
56
56
  :options_for_select,
57
57
  :collection_select,
58
- :country_select,
59
58
  :time_zone_select,
60
59
  :options_from_collection_for_select,
61
60
  :option_groups_from_collection_for_select,
62
- :country_options_for_select,
63
61
  :time_zone_options_for_select
64
62
 
65
63
  # ActionView::Helpers::PrototypeHelper
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::ActiveRecordHelper are properly
4
4
  # escaped.
5
- class ActiveRecordHelper < Test::Unit::TestCase
5
+ class ActiveRecordHelper < ActionView::TestCase
6
6
 
7
7
  def setup
8
8
  @errors = mock()
@@ -18,7 +18,7 @@ class ActiveRecordHelper < Test::Unit::TestCase
18
18
  @errors.stubs(:on).with(:bar).returns('foo&bar')
19
19
  assert_render({
20
20
  %(<%= error_message_on :foo, :bar %>) => %(
21
- <div class="formError">foo&bar</div>)
21
+ <div class="formError">foo&amp;bar</div>)
22
22
  }, @options)
23
23
  end
24
24
 
@@ -29,7 +29,7 @@ class ActiveRecordHelper < Test::Unit::TestCase
29
29
  %(<%= error_messages_for :foo %>) => %(
30
30
  <div class="errorExplanation" id="errorExplanation"><h2>1 error \
31
31
  prohibited this foo from being saved</h2><p>There were problems with the \
32
- following fields:</p><ul><li>foo&bar</li></ul></div>)
32
+ following fields:</p><ul><li>foo&amp;bar</li></ul></div>)
33
33
  }, @options)
34
34
  end
35
35
 
@@ -37,8 +37,8 @@ following fields:</p><ul><li>foo&bar</li></ul></div>)
37
37
  @foo.stubs(:new_record?).returns(true)
38
38
  assert_render({
39
39
  %(<%= form :foo %>) => %(
40
- <form action="/test/foobar" method="post">foo&name<input name="commit" \
41
- type="submit" value="Create"#{XHTML_TAGS}></form>)
40
+ <form action="/test/foobar" method="post">foo&name<input name="\
41
+ commit" type="submit" value="Create"#{XHTML_TAGS}></form>)
42
42
  }, @options)
43
43
  end
44
44
 
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from Synthesis::AssetPackagerHelper are properly escaped.
4
- class AssetPackagerTest < Test::Unit::TestCase
4
+ class AssetPackagerTest < ActionView::TestCase
5
5
 
6
6
  $asset_packages_yml = {
7
7
  "javascripts" => [{ "base" => [ "foobar" ] }],
@@ -10,7 +10,7 @@ class AssetPackagerTest < Test::Unit::TestCase
10
10
  include Synthesis::AssetPackageHelper
11
11
 
12
12
  rescue NameError
13
- puts "AssetPackager plugin not found, skipping related tests"
13
+ puts "Skipping AssetPackger plugin tests"
14
14
 
15
15
  else
16
16
 
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::AssetTagHelper are properly
4
4
  # escaped.
5
- class AssetTagHelper < Test::Unit::TestCase
5
+ class AssetTagHelper < ActionView::TestCase
6
6
 
7
7
  def test_auto_discovery_link_tag
8
8
  assert_render(
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::DateHelper are properly
4
4
  # escaped.
5
- class DateHelperTest < Test::Unit::TestCase
5
+ class DateHelperTest < ActionView::TestCase
6
6
 
7
7
  def test_date_select
8
8
  assert_render_has_no_escaped_chars %(<%= date_select :foo, :created_on %>)
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ERB::Util are properly escaped.
4
- class ErbUtilTest< Test::Unit::TestCase
4
+ class ErbUtilTest< ActionView::TestCase
5
5
 
6
6
  # h is an alias for html_escape.
7
7
  def test_html_escape
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::FormHelper are properly escaped.
4
- class FormHelperTest < Test::Unit::TestCase
4
+ class FormHelperTest < ActionView::TestCase
5
5
 
6
6
  def setup
7
7
  @options = { :locals => { :@foo => stub(:bar => "f&b") } }
@@ -10,14 +10,16 @@ class FormHelperTest < Test::Unit::TestCase
10
10
  def test_check_box
11
11
  assert_render({
12
12
  %(<%= check_box :foo, :bar %>) => %(
13
- <input name="foo[bar]" type="checkbox" id="foo_bar" value="1" /><input name="foo[bar]" type="hidden" value="0" />)
13
+ <input name="foo[bar]" type="hidden" value="0" />\
14
+ <input name="foo[bar]" id="foo_bar" value="1" type="checkbox" />)
14
15
  }, @options)
15
16
  end
16
17
 
17
18
  def test_fields_for
18
19
  assert_render({
19
20
  %(<% fields_for @foo.bar do |fields| %>Field: <%= fields.check_box :field %><% end %>) => %(
20
- Field: <input name="f&amp;b[field]" type="checkbox" id="f_b_field" value="1" /><input name="f&amp;b[field]" type="hidden" value="0" />)
21
+ Field: <input name="f&amp;b[field]" type="hidden" value="0" />\
22
+ <input name="f&amp;b[field]" type="checkbox" id="f_b_field" value="1" />)
21
23
  }, @options)
22
24
  end
23
25
 
@@ -31,7 +33,7 @@ class FormHelperTest < Test::Unit::TestCase
31
33
  def test_form_for
32
34
  assert_render({
33
35
  %(<% form_for :foo do |f| %>Bar: <%= f.text_field :bar %><% end %>) => %(
34
- <form action="/test/foobar" method="post">Bar: <input name="foo[bar]" size="30" type="text" id="foo_bar" value="f&amp;b" /></form>)
36
+ <form method=\"post\" action=\"/test/foobar\">Bar: <input name=\"foo[bar]\" size=\"30\" id=\"foo_bar\" value=\"f&amp;b\" type=\"text\" /></form>)
35
37
  }, @options)
36
38
  end
37
39
 
@@ -51,28 +53,28 @@ class FormHelperTest < Test::Unit::TestCase
51
53
  def test_password_field
52
54
  assert_render({
53
55
  %(<%= password_field :foo, :bar %>) => %(
54
- <input name="foo[bar]" size="30" type="password" id="foo_bar" value="f&amp;b" />)
56
+ <input name="foo[bar]" size="30" type="password" id="foo_bar" value="f&amp;b" />)
55
57
  }, @options)
56
58
  end
57
59
 
58
60
  def test_radio_button
59
61
  assert_render({
60
62
  %(<%= radio_button :foo, :bar, 'f&b' %>) => %(
61
- <input name="foo[bar]" checked="checked" type="radio" id="foo_bar_fb" value="f&amp;b" />)
63
+ <input name="foo[bar]" checked="checked" type="radio" id="foo_bar_fb" value="f&amp;b" />)
62
64
  }, @options)
63
65
  end
64
66
 
65
67
  def test_text_area
66
68
  assert_render({
67
69
  %(<%= text_area :foo, :bar %>) => %(
68
- <textarea name="foo[bar]" id="foo_bar" rows="20" cols="40">f&amp;b</textarea>)
70
+ <textarea name="foo[bar]" id="foo_bar" rows="20" cols="40">f&amp;b</textarea>)
69
71
  }, @options)
70
72
  end
71
73
 
72
74
  def test_text_field
73
75
  assert_render({
74
76
  %(<%= text_field :foo, :bar %>) => %(
75
- <input name="foo[bar]" size="30" type="text" id="foo_bar" value="f&amp;b" />)
77
+ <input name="foo[bar]" size="30" type="text" id="foo_bar" value="f&amp;b" />)
76
78
  }, @options)
77
79
  end
78
80
 
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::FormOptionsHelper are properly
4
4
  # escaped.
5
- class FormOptionsHelperTest < Test::Unit::TestCase
5
+ class FormOptionsHelperTest < ActionView::TestCase
6
6
 
7
7
  def setup
8
8
  @options = {
@@ -17,14 +17,6 @@ class FormOptionsHelperTest < Test::Unit::TestCase
17
17
  }, @options)
18
18
  end
19
19
 
20
- def test_country_options_for_select
21
- assert_render_has_no_escaped_chars %(<%= country_options_for_select %>")
22
- end
23
-
24
- def test_country_select
25
- assert_render_has_no_escaped_chars %(<%= country_select :foo, :bar %>)
26
- end
27
-
28
20
  def test_option_groups_from_collection_for_select
29
21
  continents = [
30
22
  stub(:id => 1,
@@ -40,8 +32,9 @@ class FormOptionsHelperTest < Test::Unit::TestCase
40
32
 
41
33
  def test_options_for_select
42
34
  assert_render(
43
- %(<%= options_for_select 'a&b', 'c&d' %>) => %(
44
- <option value="a&amp;b">a&amp;b</option>))
35
+ %(<%= options_for_select ['a&b', 'c&d'] %>) => %(
36
+ <option value="a&amp;b">a&amp;b</option>
37
+ <option value="c&amp;d">c&amp;d</option>))
45
38
  end
46
39
 
47
40
  def test_options_from_collection_for_select
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::FormTagHelper are properly
4
4
  # escaped.
5
- class FormTagHelperTest < Test::Unit::TestCase
5
+ class FormTagHelperTest < ActionView::TestCase
6
6
 
7
7
  def test_check_box_tag
8
8
  assert_render(
@@ -20,7 +20,7 @@ class FormTagHelperTest < Test::Unit::TestCase
20
20
  def test_file_field_tag
21
21
  assert_render(
22
22
  %(<%= file_field_tag 'foo&bar' %>) => %(
23
- <input name="foo&amp;bar" type="file" id="foo&amp;bar"#{XHTML_TAGS}>))
23
+ <input name="foo&amp;bar" type="file" id="foo_bar"#{XHTML_TAGS}>))
24
24
  end
25
25
 
26
26
  def test_form_tag
@@ -33,7 +33,7 @@ class FormTagHelperTest < Test::Unit::TestCase
33
33
  def test_hidden_field_tag
34
34
  assert_render(
35
35
  %(<%= hidden_field_tag 'foo&bar' %>) => %(
36
- <input name="foo&amp;bar" type="hidden" id="foo&amp;bar"#{XHTML_TAGS}>))
36
+ <input name="foo&amp;bar" type="hidden" id="foo_bar"#{XHTML_TAGS}>))
37
37
  end
38
38
 
39
39
  def test_image_submit_tag
@@ -45,13 +45,13 @@ class FormTagHelperTest < Test::Unit::TestCase
45
45
  def test_label_tag
46
46
  assert_render(
47
47
  %(<%= label_tag 'foo&bar' %>) => %(
48
- <label for="foo&amp;bar">Foo&bar</label>))
48
+ <label for="foo_bar">Foo&bar</label>))
49
49
  end
50
50
 
51
51
  def test_password_field_tag
52
52
  assert_render(
53
53
  %(<%= password_field_tag 'foo&bar' %>) => %(
54
- <input name="foo&amp;bar" type="password" id="foo&amp;bar"#{XHTML_TAGS}>))
54
+ <input name="foo&amp;bar" type="password" id="foo_bar"#{XHTML_TAGS}>))
55
55
  end
56
56
 
57
57
  def test_radio_button_tag
@@ -64,7 +64,7 @@ class FormTagHelperTest < Test::Unit::TestCase
64
64
  def test_select_tag
65
65
  assert_render(
66
66
  %(<%= select_tag 'foo&bar' %>) => %(
67
- <select name="foo&amp;bar" id="foo&amp;bar"></select>))
67
+ <select name="foo&amp;bar" id="foo_bar"></select>))
68
68
  end
69
69
 
70
70
  def test_submit_tag
@@ -76,13 +76,13 @@ class FormTagHelperTest < Test::Unit::TestCase
76
76
  def test_text_area_tag
77
77
  assert_render(
78
78
  %(<%= text_area_tag 'foo&bar' %>) => %(
79
- <textarea name="foo&amp;bar" id="foo&amp;bar"></textarea>))
79
+ <textarea name="foo&amp;bar" id="foo_bar"></textarea>))
80
80
  end
81
81
 
82
82
  def test_text_field_tag
83
83
  assert_render(
84
84
  %(<%= text_field_tag 'foo&bar' %>) => %(
85
- <input name="foo&amp;bar" type="text" id="foo&amp;bar"#{XHTML_TAGS}>))
85
+ <input name="foo&amp;bar" type="text" id="foo_bar"#{XHTML_TAGS}>))
86
86
  end
87
87
 
88
88
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::JavaScriptHelper are properly
4
4
  # escaped.
5
- class JavascriptHelperTest < Test::Unit::TestCase
5
+ class JavascriptHelperTest < ActionView::TestCase
6
6
 
7
7
  def test_button_to_function
8
8
  assert_render(
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
3
  # Test that helpers from ActionView::Helpers::PrototypeHelper are escaped
4
4
  # correctly.
5
- class PrototypeHelperTest < Test::Unit::TestCase
5
+ class PrototypeHelperTest < ActionView::TestCase
6
6
 
7
7
  def test_evaluate_remote_response
8
8
  assert_render(
@@ -54,7 +54,7 @@ new PeriodicalExecuter(function() {new Ajax.Request('/test/foobar', \
54
54
  %(<%= submit_to_remote 'foo&bar', 'f&b' %>) => %(
55
55
  <input name="foo&amp;bar" value="f&amp;b" type="button" onclick="\
56
56
  new Ajax.Request('/test/foobar', {asynchronous:true, evalScripts:true, \
57
- parameters:Form.serialize(this.form)}); return false;"#{XHTML_TAGS}>))
57
+ parameters:Form.serialize(this.form)});"#{XHTML_TAGS}>))
58
58
  end
59
59
 
60
60
  end
@@ -5,29 +5,16 @@ require File.dirname(__FILE__) + '/../test/test_helper'
5
5
  class TemplateObjectTest < Test::Unit::TestCase
6
6
 
7
7
  def setup
8
- @view = ActionView::Base.new(VIEW_PATH)
9
- @path = "hello_world.erb"
8
+ @template_path = VIEW_PATH + "/hello_world.erb"
10
9
  end
11
10
 
12
- def test_should_create_valid_template
13
- template = ActionView::Template.new(@view, @path, true)
11
+ def test_create_valid_template
12
+ template = ActionView::Template.new(@template_path, true)
14
13
 
15
- assert_kind_of ActionView::TemplateHandlers::ERB, template.handler
16
- assert_equal "hello_world.erb", template.path
14
+ assert_equal ActionView::TemplateHandlers::XssShieldERB, template.handler
15
+ assert_equal @template_path, template.path
17
16
  assert_nil template.instance_variable_get(:"@source")
18
17
  assert_equal "erb", template.extension
19
18
  end
20
19
 
21
- def test_should_prepare_template_properly
22
- template = ActionView::Template.new(@view, @path, true)
23
- view = template.instance_variable_get(:"@view")
24
-
25
- view.expects(:evaluate_assigns)
26
- template.handler.expects(:compile_template).with(template)
27
- view.expects(:method_names).returns({})
28
-
29
- template.prepare!
30
- end
31
-
32
20
  end
33
-
data/test/test_helper.rb CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  require File.expand_path "#{CUR_DIR}/../../../../test/test_helper"
7
7
  rescue LoadError
8
8
  require 'rubygems'
9
- gem 'rails', '=2.1.2'
9
+ gem 'rails', '=2.3.4'
10
10
  require 'active_record'
11
11
  require 'action_controller'
12
12
  require 'action_controller/test_process'
@@ -34,7 +34,7 @@ end
34
34
  class Test::Unit::TestCase
35
35
 
36
36
  VIEW_PATH = File.join(File.dirname(__FILE__), 'fixtures')
37
- ActionView::TemplateFinder.process_view_paths(VIEW_PATH)
37
+ ActionController::Base.prepend_view_path(VIEW_PATH)
38
38
 
39
39
  private
40
40
 
@@ -47,12 +47,20 @@ class Test::Unit::TestCase
47
47
  def assert_render(args, options = {})
48
48
  args.each do |erb, expected|
49
49
  expected.strip!
50
- actual = render_erb(erb, options[:locals])
51
- assert_dom_equal expected, actual, "#{erb} => #{expected}"
50
+ begin
51
+ actual = render_erb(erb, options[:locals])
52
+ rescue Exception => ex
53
+ puts "ERB: #{erb} => Expected: #{expected}"
54
+ puts ex.message
55
+ puts ex.backtrace
56
+ end
57
+ assert_dom_equal actual, expected, "ERB: #{erb}"
52
58
  end
53
59
  end
54
60
 
55
- def render_erb(erb, locals = {})
61
+ def render_erb(erb, variables)
62
+ variables ||= {}
63
+
56
64
  # Need this to make asset packager happy.
57
65
  request = mock()
58
66
  request.stubs(:relative_url_root).returns('')
@@ -65,7 +73,20 @@ class Test::Unit::TestCase
65
73
  controller.stubs(:url_for).returns('/test/foobar')
66
74
 
67
75
  view = ActionView::Base.new(VIEW_PATH, {}, controller)
68
- ActionView::InlineTemplate.new(view, erb, locals).render.strip
76
+
77
+ template = ActionView::InlineTemplate.new(erb)
78
+ template.stubs(:relative_path).returns('/')
79
+
80
+ # Set instance variables
81
+ locals = variables.dup
82
+ variables.each do |key, value|
83
+ if key.to_s.start_with?('@')
84
+ view.instance_variable_set(key, value)
85
+ locals.delete(key)
86
+ end
87
+ end
88
+
89
+ template.render(view, locals).strip
69
90
  end
70
91
 
71
92
  end
@@ -1,8 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test/test_helper'
2
2
 
3
- # Test that helpers from ActionView::Helpers::UrlHelper are properly
4
- # escaped.
5
- class UrlHelperTest < Test::Unit::TestCase
3
+ # Test that helpers from ActionView::Helpers::UrlHelper are properly escaped.
4
+ class UrlHelperTest < ActionView::TestCase
6
5
 
7
6
  def test_button_to
8
7
  assert_render(
data/xss_shield.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{xss_shield}
8
- s.version = "1.0.0"
8
+ s.version = "2.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["James Tan"]
@@ -16,7 +16,8 @@ Gem::Specification.new do |s|
16
16
  "README.rdoc"
17
17
  ]
18
18
  s.files = [
19
- "MIT-LICENSE",
19
+ ".gitignore",
20
+ "MIT-LICENSE",
20
21
  "README.rdoc",
21
22
  "Rakefile",
22
23
  "VERSION",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xss_shield
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Tan
@@ -22,6 +22,7 @@ extensions: []
22
22
  extra_rdoc_files:
23
23
  - README.rdoc
24
24
  files:
25
+ - .gitignore
25
26
  - MIT-LICENSE
26
27
  - README.rdoc
27
28
  - Rakefile