rails_xss 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 joloudov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = rails_xss
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 joloudov. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rails_xss"
8
+ gem.summary = %Q{A plugin for rails 2.3 apps which switches the default to escape by default}
9
+ gem.description = %Q{This plugin replaces the default ERB template handlers with erubis, and switches the behaviour to escape by default rather than requiring you to escape. This is consistent with the behaviour in Rails 3.0.}
10
+ gem.email = "joloudov@gmail.com"
11
+ gem.homepage = "http://github.com/joloudov/rails_xss"
12
+ gem.authors = ["joloudov"]
13
+ gem.add_development_dependency "erubis", ">= 2.6.5"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "rails_xss #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rails_xss.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'rails_xss/erubis'
2
+ require 'rails_xss/action_view'
3
+ require 'rails_xss/string_ext'
@@ -0,0 +1,74 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveRecordHelperTest < ActionView::TestCase
4
+ silence_warnings do
5
+ Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
6
+ Post.class_eval do
7
+ alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
8
+ alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
9
+ alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
10
+ end
11
+ end
12
+
13
+ def setup_post
14
+ @post = Post.new
15
+ def @post.errors
16
+ Class.new {
17
+ def on(field)
18
+ case field.to_s
19
+ when "author_name"
20
+ "can't be empty"
21
+ when "body"
22
+ true
23
+ else
24
+ false
25
+ end
26
+ end
27
+ def empty?() false end
28
+ def count() 1 end
29
+ def full_messages() [ "Author name can't be empty" ] end
30
+ }.new
31
+ end
32
+
33
+ def @post.new_record?() true end
34
+ def @post.to_param() nil end
35
+
36
+ def @post.column_for_attribute(attr_name)
37
+ Post.content_columns.select { |column| column.name == attr_name }.first
38
+ end
39
+
40
+ silence_warnings do
41
+ def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
42
+ end
43
+
44
+ @post.title = "Hello World"
45
+ @post.author_name = ""
46
+ @post.body = "Back to the hill and over it again!"
47
+ @post.secret = 1
48
+ @post.written_on = Date.new(2004, 6, 15)
49
+ end
50
+
51
+ def setup
52
+ setup_post
53
+
54
+ @response = ActionController::TestResponse.new
55
+
56
+ @controller = Object.new
57
+ def @controller.url_for(options)
58
+ options = options.symbolize_keys
59
+
60
+ [options[:action], options[:id].to_param].compact.join('/')
61
+ end
62
+ end
63
+
64
+ def test_text_field_with_errors_is_safe
65
+ assert text_field("post", "author_name").html_safe?
66
+ end
67
+
68
+ def test_text_field_with_errors
69
+ assert_dom_equal(
70
+ %(<div class="fieldWithErrors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /></div>),
71
+ text_field("post", "author_name")
72
+ )
73
+ end
74
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class AssetTagHelperTest < ActionView::TestCase
4
+ def setup
5
+ @controller = Class.new do
6
+ attr_accessor :request
7
+ def url_for(*args) "http://www.example.com" end
8
+ end.new
9
+ end
10
+
11
+ def test_auto_discovery_link_tag
12
+ assert_dom_equal(%(<link href="http://www.example.com" rel="Not so alternate" title="ATOM" type="application/atom+xml" />),
13
+ auto_discovery_link_tag(:atom, {}, {:rel => "Not so alternate"}))
14
+ end
15
+
16
+ def test_javascript_include_tag_with_blank_asset_id
17
+ ENV["RAILS_ASSET_ID"] = ""
18
+ assert_dom_equal(%(<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
19
+ javascript_include_tag("test", :defaults))
20
+ end
21
+
22
+ def test_javascript_include_tag_with_given_asset_id
23
+ ENV["RAILS_ASSET_ID"] = "1"
24
+ assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>),
25
+ javascript_include_tag(:defaults))
26
+ ENV["RAILS_ASSET_ID"] = ""
27
+ end
28
+
29
+ def test_javascript_include_tag_is_html_safe
30
+ assert javascript_include_tag(:defaults).html_safe?
31
+ assert javascript_include_tag("prototype").html_safe?
32
+ end
33
+
34
+ def test_stylesheet_link_tag
35
+ assert_dom_equal(%(<link href="http://www.example.com/styles/style.css" media="screen" rel="stylesheet" type="text/css" />),
36
+ stylesheet_link_tag("http://www.example.com/styles/style"))
37
+ end
38
+
39
+ def test_stylesheet_link_tag_is_html_safe
40
+ assert stylesheet_link_tag('dir/file').html_safe?
41
+ assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
42
+ assert stylesheet_tag('dir/file', {}).html_safe?
43
+ end
44
+
45
+ def test_image_tag
46
+ assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />),
47
+ image_tag("mouse.png", :mouseover => image_path("mouse_over.png")))
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ CACHE_DIR = 'test_cache'
4
+ # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
5
+ FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
6
+ ActionController::Base.page_cache_directory = FILE_STORE_PATH
7
+ ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
8
+
9
+ class FragmentCachingTestController < ActionController::Base
10
+ def some_action; end;
11
+ end
12
+
13
+ class FragmentCachingTest < ActionController::TestCase
14
+ def setup
15
+ ActionController::Base.perform_caching = true
16
+ @store = ActiveSupport::Cache::MemoryStore.new
17
+ ActionController::Base.cache_store = @store
18
+ @controller = FragmentCachingTestController.new
19
+ @params = {:controller => 'posts', :action => 'index'}
20
+ @request = ActionController::TestRequest.new
21
+ @response = ActionController::TestResponse.new
22
+ @controller.params = @params
23
+ @controller.request = @request
24
+ @controller.response = @response
25
+ @controller.send(:initialize_current_url)
26
+ @controller.send(:initialize_template_class, @response)
27
+ @controller.send(:assign_shortcuts, @request, @response)
28
+ end
29
+
30
+ def test_html_safety
31
+ assert_nil @store.read('views/name')
32
+ content = 'value'.html_safe
33
+ assert_equal content, @controller.write_fragment('name', content)
34
+
35
+ cached = @store.read('views/name')
36
+ assert_equal content, cached
37
+ assert_equal String, cached.class
38
+
39
+ html_safe = @controller.read_fragment('name')
40
+ assert_equal content, html_safe
41
+ assert html_safe.html_safe?
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+ class DateHelperTest < ActionView::TestCase
4
+ silence_warnings do
5
+ Post = Struct.new("Post", :id, :written_on, :updated_at)
6
+ end
7
+
8
+ def test_select_html_safety
9
+ assert select_day(16).html_safe?
10
+ assert select_month(8).html_safe?
11
+ assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
12
+ assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
13
+ assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
14
+
15
+ assert select_minute(8, :use_hidden => true).html_safe?
16
+ assert select_month(8, :prompt => 'Choose month').html_safe?
17
+
18
+ assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, :class => 'selector').html_safe?
19
+ assert select_date(Time.mktime(2003, 8, 16), :date_separator => " / ", :start_year => 2003, :end_year => 2005, :prefix => "date[first]").html_safe?
20
+ end
21
+
22
+ def test_object_select_html_safety
23
+ @post = Post.new
24
+ @post.written_on = Date.new(2004, 6, 15)
25
+
26
+ assert date_select("post", "written_on", :default => Time.local(2006, 9, 19, 15, 16, 35), :include_blank => true).html_safe?
27
+ assert time_select("post", "written_on", :ignore_date => true).html_safe?
28
+ end
29
+ end
@@ -0,0 +1,112 @@
1
+ require 'test_helper'
2
+
3
+ class DeprecatedOutputSafetyTest < ActiveSupport::TestCase
4
+ def setup
5
+ @string = "hello"
6
+ end
7
+
8
+ test "A string can be marked safe using html_safe!" do
9
+ assert_deprecated do
10
+ @string.html_safe!
11
+ assert @string.html_safe?
12
+ end
13
+ end
14
+
15
+ test "Marking a string safe returns the string using html_safe!" do
16
+ assert_deprecated do
17
+ assert_equal @string, @string.html_safe!
18
+ end
19
+ end
20
+
21
+ test "Adding a safe string to another safe string returns a safe string using html_safe!" do
22
+ assert_deprecated do
23
+ @other_string = "other".html_safe!
24
+ @string.html_safe!
25
+ @combination = @other_string + @string
26
+
27
+ assert_equal "otherhello", @combination
28
+ assert @combination.html_safe?
29
+ end
30
+ end
31
+
32
+ test "Adding an unsafe string to a safe string returns an unsafe string using html_safe!" do
33
+ assert_deprecated do
34
+ @other_string = "other".html_safe!
35
+ @combination = @other_string + "<foo>"
36
+ @other_combination = @string + "<foo>"
37
+
38
+ assert_equal "other<foo>", @combination
39
+ assert_equal "hello<foo>", @other_combination
40
+
41
+ assert !@combination.html_safe?
42
+ assert !@other_combination.html_safe?
43
+ end
44
+ end
45
+
46
+ test "Concatting safe onto unsafe yields unsafe using html_safe!" do
47
+ assert_deprecated do
48
+ @other_string = "other"
49
+ @string.html_safe!
50
+
51
+ @other_string.concat(@string)
52
+ assert !@other_string.html_safe?
53
+ end
54
+ end
55
+
56
+ test "Concatting unsafe onto safe yields unsafe using html_safe!" do
57
+ assert_deprecated do
58
+ @other_string = "other".html_safe!
59
+ string = @other_string.concat("<foo>")
60
+ assert_equal "other<foo>", string
61
+ assert !string.html_safe?
62
+ end
63
+ end
64
+
65
+ test "Concatting safe onto safe yields safe using html_safe!" do
66
+ assert_deprecated do
67
+ @other_string = "other".html_safe!
68
+ @string.html_safe!
69
+
70
+ @other_string.concat(@string)
71
+ assert @other_string.html_safe?
72
+ end
73
+ end
74
+
75
+ test "Concatting safe onto unsafe with << yields unsafe using html_safe!" do
76
+ assert_deprecated do
77
+ @other_string = "other"
78
+ @string.html_safe!
79
+
80
+ @other_string << @string
81
+ assert !@other_string.html_safe?
82
+ end
83
+ end
84
+
85
+ test "Concatting unsafe onto safe with << yields unsafe using html_safe!" do
86
+ assert_deprecated do
87
+ @other_string = "other".html_safe!
88
+ string = @other_string << "<foo>"
89
+ assert_equal "other<foo>", string
90
+ assert !string.html_safe?
91
+ end
92
+ end
93
+
94
+ test "Concatting safe onto safe with << yields safe using html_safe!" do
95
+ assert_deprecated do
96
+ @other_string = "other".html_safe!
97
+ @string.html_safe!
98
+
99
+ @other_string << @string
100
+ assert @other_string.html_safe?
101
+ end
102
+ end
103
+
104
+ test "Concatting a fixnum to safe always yields safe using html_safe!" do
105
+ assert_deprecated do
106
+ @string.html_safe!
107
+ @string.concat(13)
108
+ assert_equal "hello".concat(13), @string
109
+ assert @string.html_safe?
110
+ end
111
+ end
112
+ end