inquisition 0.2 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +11 -4
- data/lib/inquisition.rb +41 -18
- data/test/inquisition_test.rb +37 -0
- data/test/models.rb +2 -2
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=
|
1
|
+
= Inquisition
|
2
2
|
|
3
3
|
== Introduction
|
4
4
|
|
@@ -9,14 +9,21 @@ It keeps your strings heresy-free.
|
|
9
9
|
|
10
10
|
Inquisition offers you three methods on Object:
|
11
11
|
|
12
|
-
cleanse_attr *attributes
|
13
|
-
cleanse_attr_reader *attributes
|
14
|
-
cleanse_attr_writer *attributes
|
12
|
+
cleanse_attr *attributes, options
|
13
|
+
cleanse_attr_reader *attributes, options
|
14
|
+
cleanse_attr_writer *attributes, options
|
15
15
|
|
16
16
|
These methods will wrap your getters and/or setters for an attribute through a
|
17
17
|
HTML5 Sanitizer. This should help to protect against most kinds of cross site
|
18
18
|
scripting attacks.
|
19
19
|
|
20
|
+
For example:
|
21
|
+
|
22
|
+
cleanse_attr :name, :allow => {:name => /(<strong>)/}
|
23
|
+
|
24
|
+
The above example will clean all values written to or read from the name
|
25
|
+
attribute, but will not remove strong tags.
|
26
|
+
|
20
27
|
== Installation
|
21
28
|
|
22
29
|
sudo gem install thumblemonks-inquisition
|
data/lib/inquisition.rb
CHANGED
@@ -10,6 +10,14 @@ module Inquisition
|
|
10
10
|
klass.extend(ClassMethods)
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.sanitize(value, allow)
|
14
|
+
if allow && match = Regexp.new(allow).match(value)
|
15
|
+
[HTML5libSanitize.sanitize_html(match.pre_match), match.to_a.first, self.sanitize(match.post_match, allow)].join
|
16
|
+
else
|
17
|
+
HTML5libSanitize.sanitize_html(value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
module ClassMethods
|
14
22
|
def sanitize_attribute(*attributes)
|
15
23
|
sanitize_attribute_reader(*attributes)
|
@@ -17,34 +25,49 @@ module Inquisition
|
|
17
25
|
end
|
18
26
|
|
19
27
|
def sanitize_attribute_reader(*attributes)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
options = attributes.last.is_a?(::Hash) ? attributes.pop : {}
|
29
|
+
if respond_to?(:cleansed_attr_readers)
|
30
|
+
write_inheritable_attribute(:cleansed_attr_readers, cleansed_attr_readers.concat(attributes))
|
31
|
+
write_inheritable_attribute(:cleansed_attr_reader_options, cleansed_attr_reader_options.merge(options))
|
32
|
+
else
|
33
|
+
write_inheritable_attribute(:cleansed_attr_readers, attributes)
|
34
|
+
write_inheritable_attribute(:cleansed_attr_reader_options, options)
|
35
|
+
class_inheritable_reader(:cleansed_attr_readers)
|
36
|
+
class_inheritable_reader(:cleansed_attr_reader_options)
|
37
|
+
|
38
|
+
define_method(:read_attribute_with_cleansing) do |attribute|
|
39
|
+
value = read_attribute_without_cleansing(attribute)
|
40
|
+
if cleansed_attr_readers.include?(attribute.to_sym) && !value.blank?
|
41
|
+
Inquisition.sanitize(value,cleansed_attr_reader_options[:allow][attribute.to_sym])
|
42
|
+
else
|
43
|
+
value
|
44
|
+
end
|
29
45
|
end
|
46
|
+
alias_method_chain :read_attribute, :cleansing
|
30
47
|
end
|
31
|
-
alias_method_chain :read_attribute, :cleansing
|
32
48
|
|
33
49
|
attributes.each { |attr| define_method(attr.to_sym) { read_attribute(attr.to_sym) } }
|
34
50
|
end
|
35
51
|
|
36
52
|
def sanitize_attribute_writer(*attributes)
|
37
|
-
|
38
|
-
|
53
|
+
options = attributes.last.is_a?(::Hash) ? attributes.pop : {}
|
54
|
+
if respond_to?(:cleansed_attr_writers)
|
55
|
+
write_inheritable_attribute(:cleansed_attr_writers, cleansed_attr_writers.concat(attributes))
|
56
|
+
write_inheritable_attribute(:cleansed_attr_writer_options, cleansed_attr_writer_options.merge(options))
|
57
|
+
else
|
58
|
+
write_inheritable_attribute(:cleansed_attr_writers, attributes)
|
59
|
+
write_inheritable_attribute(:cleansed_attr_writer_options, options)
|
60
|
+
class_inheritable_reader(:cleansed_attr_writers)
|
61
|
+
class_inheritable_reader(:cleansed_attr_writer_options)
|
39
62
|
|
40
|
-
|
41
|
-
|
42
|
-
|
63
|
+
define_method(:write_attribute_with_cleansing) do |attribute, value|
|
64
|
+
if cleansed_attr_writers.include?(attribute.to_sym) && !value.blank?
|
65
|
+
Inquisition.sanitize(value,cleansed_attr_writer_options[:allow][attribute.to_sym])
|
66
|
+
end
|
67
|
+
write_attribute_without_cleansing(attribute, value)
|
43
68
|
end
|
44
|
-
|
45
|
-
write_attribute_without_cleansing(attribute, value)
|
69
|
+
alias_method_chain :write_attribute, :cleansing
|
46
70
|
end
|
47
|
-
alias_method_chain :write_attribute, :cleansing
|
48
71
|
end
|
49
72
|
end #Class Methods
|
50
73
|
end #Inquisition
|
data/test/inquisition_test.rb
CHANGED
@@ -47,4 +47,41 @@ class InquisitionTest < Test::Unit::TestCase
|
|
47
47
|
assert_equal nil, @whisky.name
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
context "allowing a single character" do
|
52
|
+
setup do
|
53
|
+
@dumb_phrase = "Central Time (US & Canada)"
|
54
|
+
@clean_dumb = "Central Time (US & Canada)"
|
55
|
+
@whisky = Whisky.new(:description => @dumb_phrase, :name => @dumb_phrase)
|
56
|
+
end
|
57
|
+
|
58
|
+
should "allow ampersands in the description" do
|
59
|
+
assert_equal @dumb_phrase, @whisky.description
|
60
|
+
end
|
61
|
+
|
62
|
+
should "not allow ampersands in the name" do
|
63
|
+
assert_equal @clean_dumb, @whisky.name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "allowing a regexp" do
|
68
|
+
setup do
|
69
|
+
@dumb_phrase = "<buttes> hey guy, I think <buttes> about <buttes>, because i have no clear opinion on <buttes>"
|
70
|
+
@clean_phrase = "<buttes> hey guy, I think <buttes> about <buttes>, because i have no clear opinion on <buttes>"
|
71
|
+
@whisky = Whisky.new(:measure => @dumb_phrase, :name => @dumb_phrase)
|
72
|
+
end
|
73
|
+
|
74
|
+
should "allow the regexp'd phrase in the measure" do
|
75
|
+
assert_equal @dumb_phrase, @whisky.measure
|
76
|
+
end
|
77
|
+
|
78
|
+
should "not allow the regexp'd phrase in the name" do
|
79
|
+
assert_equal @clean_phrase, @whisky.name
|
80
|
+
end
|
81
|
+
|
82
|
+
should "still clean non-matched parts" do
|
83
|
+
@whisky.measure = "<script>alert('Cragganmore')</script>"
|
84
|
+
assert_equal "<script>alert('Cragganmore')</script>", @whisky.measure
|
85
|
+
end
|
86
|
+
end
|
50
87
|
end
|
data/test/models.rb
CHANGED
@@ -3,7 +3,7 @@ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => File
|
|
3
3
|
class CreateSchema < ActiveRecord::Migration
|
4
4
|
def self.up
|
5
5
|
create_table :whiskies, :force => true do |t|
|
6
|
-
t.string :name, :origin, :description
|
6
|
+
t.string :name, :origin, :description, :measure
|
7
7
|
t.integer :abv
|
8
8
|
end
|
9
9
|
create_table :animals, :force => true do |t|
|
@@ -21,7 +21,7 @@ class Animal < ActiveRecord::Base
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class Whisky < ActiveRecord::Base
|
24
|
-
sanitize_attribute :name, :description
|
24
|
+
sanitize_attribute :name, :description, :measure, :allow => { :description => "&", :measure => /(<buttes>)/ }
|
25
25
|
|
26
26
|
def drink
|
27
27
|
"You quaffed #{description}"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inquisition
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.3"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- toothrot
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-11 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -69,7 +69,7 @@ requirements: []
|
|
69
69
|
rubyforge_project:
|
70
70
|
rubygems_version: 1.3.5
|
71
71
|
signing_key:
|
72
|
-
specification_version:
|
72
|
+
specification_version: 3
|
73
73
|
summary: Inquisition is a fancy way to protect your ActiveRecord attributes from XSS
|
74
74
|
test_files: []
|
75
75
|
|