sanitize 4.6.3 → 5.1.0
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.
Potentially problematic release.
This version of sanitize might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/HISTORY.md +101 -1
- data/README.md +24 -4
- data/lib/sanitize.rb +41 -63
- data/lib/sanitize/config/default.rb +10 -4
- data/lib/sanitize/transformers/clean_element.rb +44 -3
- data/lib/sanitize/version.rb +1 -1
- data/test/common.rb +0 -31
- data/test/test_clean_comment.rb +1 -5
- data/test/test_clean_css.rb +1 -1
- data/test/test_clean_doctype.rb +8 -8
- data/test/test_clean_element.rb +108 -23
- data/test/test_malicious_html.rb +30 -6
- data/test/test_parser.rb +2 -31
- data/test/test_sanitize.rb +102 -17
- data/test/test_sanitize_css.rb +39 -12
- data/test/test_transformers.rb +22 -4
- metadata +12 -14
- data/test/test_unicode.rb +0 -95
data/test/test_sanitize_css.rb
CHANGED
@@ -196,26 +196,53 @@ describe 'Sanitize::CSS' do
|
|
196
196
|
|
197
197
|
describe 'class methods' do
|
198
198
|
describe '.properties' do
|
199
|
-
it 'should
|
200
|
-
|
201
|
-
|
202
|
-
|
199
|
+
it 'should sanitize CSS properties with the given config' do
|
200
|
+
css = 'background: #fff; width: expression(alert("hi"));'
|
201
|
+
|
202
|
+
Sanitize::CSS.properties(css).must_equal ' '
|
203
|
+
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED[:css]).must_equal 'background: #fff; '
|
204
|
+
Sanitize::CSS.properties(css, :properties => %w[background color width]).must_equal 'background: #fff; '
|
203
205
|
end
|
204
206
|
end
|
205
207
|
|
206
208
|
describe '.stylesheet' do
|
207
|
-
it 'should
|
208
|
-
|
209
|
-
|
210
|
-
|
209
|
+
it 'should sanitize a CSS stylesheet with the given config' do
|
210
|
+
css = %[
|
211
|
+
/* Yay CSS! */
|
212
|
+
.foo { color: #fff; }
|
213
|
+
#bar { background: url(yay.jpg); }
|
214
|
+
|
215
|
+
@media screen (max-width:480px) {
|
216
|
+
.foo { width: 400px; }
|
217
|
+
#bar:not(.baz) { height: 100px; }
|
218
|
+
}
|
219
|
+
].strip
|
220
|
+
|
221
|
+
Sanitize::CSS.stylesheet(css).strip.must_equal %[
|
222
|
+
.foo { }
|
223
|
+
#bar { }
|
224
|
+
].strip
|
225
|
+
|
226
|
+
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED[:css]).must_equal css
|
227
|
+
|
228
|
+
Sanitize::CSS.stylesheet(css, :properties => %w[background color width]).strip.must_equal %[
|
229
|
+
.foo { color: #fff; }
|
230
|
+
#bar { }
|
231
|
+
].strip
|
211
232
|
end
|
212
233
|
end
|
213
234
|
|
214
235
|
describe '.tree!' do
|
215
|
-
it 'should
|
216
|
-
|
217
|
-
|
218
|
-
|
236
|
+
it 'should sanitize a Crass CSS parse tree with the given config' do
|
237
|
+
tree = Crass.parse(String.new("@import url(foo.css);\n") <<
|
238
|
+
".foo { background: #fff; font: 16pt 'Comic Sans MS'; }\n" <<
|
239
|
+
"#bar { top: 125px; background: green; }")
|
240
|
+
|
241
|
+
Sanitize::CSS.tree!(tree, :properties => %w[background color width]).must_be_same_as tree
|
242
|
+
|
243
|
+
Crass::Parser.stringify(tree).must_equal String.new("\n") <<
|
244
|
+
".foo { background: #fff; }\n" <<
|
245
|
+
"#bar { background: green; }"
|
219
246
|
end
|
220
247
|
end
|
221
248
|
end
|
data/test/test_transformers.rb
CHANGED
@@ -172,28 +172,28 @@ describe 'Transformers' do
|
|
172
172
|
input = '<iframe width="420" height="315" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
|
173
173
|
|
174
174
|
Sanitize.fragment(input, :transformers => youtube_transformer)
|
175
|
-
.must_equal '<iframe width="420" height="315" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""
|
175
|
+
.must_equal '<iframe width="420" height="315" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
|
176
176
|
end
|
177
177
|
|
178
178
|
it 'should allow HTTPS YouTube video embeds' do
|
179
179
|
input = '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
|
180
180
|
|
181
181
|
Sanitize.fragment(input, :transformers => youtube_transformer)
|
182
|
-
.must_equal '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""
|
182
|
+
.must_equal '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
|
183
183
|
end
|
184
184
|
|
185
185
|
it 'should allow protocol-relative YouTube video embeds' do
|
186
186
|
input = '<iframe width="420" height="315" src="//www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
|
187
187
|
|
188
188
|
Sanitize.fragment(input, :transformers => youtube_transformer)
|
189
|
-
.must_equal '<iframe width="420" height="315" src="//www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""
|
189
|
+
.must_equal '<iframe width="420" height="315" src="//www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
|
190
190
|
end
|
191
191
|
|
192
192
|
it 'should allow privacy-enhanced YouTube video embeds' do
|
193
193
|
input = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
|
194
194
|
|
195
195
|
Sanitize.fragment(input, :transformers => youtube_transformer)
|
196
|
-
.must_equal '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""
|
196
|
+
.must_equal '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
|
197
197
|
end
|
198
198
|
|
199
199
|
it 'should not allow non-YouTube video embeds' do
|
@@ -203,4 +203,22 @@ describe 'Transformers' do
|
|
203
203
|
.must_equal('')
|
204
204
|
end
|
205
205
|
end
|
206
|
+
|
207
|
+
describe 'DOM modification transformer' do
|
208
|
+
b_to_strong_tag_transformer = lambda do |env|
|
209
|
+
node = env[:node]
|
210
|
+
node_name = env[:node_name]
|
211
|
+
|
212
|
+
if node_name == 'b'
|
213
|
+
node.name = 'strong'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should allow the <b> tag to be changed to a <strong> tag' do
|
218
|
+
input = '<b>text</b>'
|
219
|
+
|
220
|
+
Sanitize.fragment(input, :elements => ['strong'], :transformers => b_to_strong_tag_transformer)
|
221
|
+
.must_equal '<strong>text</strong>'
|
222
|
+
end
|
223
|
+
end
|
206
224
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sanitize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Grove
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: crass
|
@@ -30,56 +30,56 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.8.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.8.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: nokogumbo
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 5.
|
61
|
+
version: 5.11.3
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 5.
|
68
|
+
version: 5.11.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 12.
|
75
|
+
version: 12.3.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 12.
|
82
|
+
version: 12.3.1
|
83
83
|
description: Sanitize is a whitelist-based HTML and CSS sanitizer. Given a list of
|
84
84
|
acceptable elements, attributes, and CSS properties, Sanitize will remove all unacceptable
|
85
85
|
HTML and/or CSS from a string.
|
@@ -116,7 +116,6 @@ files:
|
|
116
116
|
- test/test_sanitize.rb
|
117
117
|
- test/test_sanitize_css.rb
|
118
118
|
- test/test_transformers.rb
|
119
|
-
- test/test_unicode.rb
|
120
119
|
homepage: https://github.com/rgrove/sanitize/
|
121
120
|
licenses:
|
122
121
|
- MIT
|
@@ -129,15 +128,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
128
|
requirements:
|
130
129
|
- - ">="
|
131
130
|
- !ruby/object:Gem::Version
|
132
|
-
version: 1.
|
131
|
+
version: 2.1.0
|
133
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
133
|
requirements:
|
135
134
|
- - ">="
|
136
135
|
- !ruby/object:Gem::Version
|
137
136
|
version: 1.2.0
|
138
137
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.7.3
|
138
|
+
rubygems_version: 3.0.3
|
141
139
|
signing_key:
|
142
140
|
specification_version: 4
|
143
141
|
summary: Whitelist-based HTML and CSS sanitizer.
|
data/test/test_unicode.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require_relative 'common'
|
3
|
-
|
4
|
-
describe 'Unicode' do
|
5
|
-
make_my_diffs_pretty!
|
6
|
-
parallelize_me!
|
7
|
-
|
8
|
-
# http://www.w3.org/TR/unicode-xml/#Charlist
|
9
|
-
describe 'Unsuitable characters' do
|
10
|
-
before do
|
11
|
-
@s = Sanitize.new(Sanitize::Config::RELAXED)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should not modify the input string' do
|
15
|
-
fragment = "a\u0340b\u0341c"
|
16
|
-
document = "a\u0340b\u0341c"
|
17
|
-
|
18
|
-
@s.document(document)
|
19
|
-
@s.fragment(fragment)
|
20
|
-
|
21
|
-
fragment.must_equal "a\u0340b\u0341c"
|
22
|
-
document.must_equal "a\u0340b\u0341c"
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should strip deprecated grave and acute clones' do
|
26
|
-
@s.document("a\u0340b\u0341c").must_equal "<html><head></head><body>abc</body></html>\n"
|
27
|
-
@s.fragment("a\u0340b\u0341c").must_equal 'abc'
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should strip deprecated Khmer characters' do
|
31
|
-
@s.document("a\u17a3b\u17d3c").must_equal "<html><head></head><body>abc</body></html>\n"
|
32
|
-
@s.fragment("a\u17a3b\u17d3c").must_equal 'abc'
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'should strip line and paragraph separator punctuation' do
|
36
|
-
@s.document("a\u2028b\u2029c").must_equal "<html><head></head><body>abc</body></html>\n"
|
37
|
-
@s.fragment("a\u2028b\u2029c").must_equal 'abc'
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should strip bidi embedding control characters' do
|
41
|
-
@s.document("a\u202ab\u202bc\u202cd\u202de\u202e")
|
42
|
-
.must_equal "<html><head></head><body>abcde</body></html>\n"
|
43
|
-
|
44
|
-
@s.fragment("a\u202ab\u202bc\u202cd\u202de\u202e")
|
45
|
-
.must_equal 'abcde'
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'should strip deprecated symmetric swapping characters' do
|
49
|
-
@s.document("a\u206ab\u206bc").must_equal "<html><head></head><body>abc</body></html>\n"
|
50
|
-
@s.fragment("a\u206ab\u206bc").must_equal 'abc'
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should strip deprecated Arabic form shaping characters' do
|
54
|
-
@s.document("a\u206cb\u206dc").must_equal "<html><head></head><body>abc</body></html>\n"
|
55
|
-
@s.fragment("a\u206cb\u206dc").must_equal 'abc'
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should strip deprecated National digit shape characters' do
|
59
|
-
@s.document("a\u206eb\u206fc").must_equal "<html><head></head><body>abc</body></html>\n"
|
60
|
-
@s.fragment("a\u206eb\u206fc").must_equal 'abc'
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'should strip interlinear annotation characters' do
|
64
|
-
@s.document("a\ufff9b\ufffac\ufffb").must_equal "<html><head></head><body>abc</body></html>\n"
|
65
|
-
@s.fragment("a\ufff9b\ufffac\ufffb").must_equal 'abc'
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'should strip BOM/zero-width non-breaking space characters' do
|
69
|
-
@s.document("a\ufeffbc").must_equal "<html><head></head><body>abc</body></html>\n"
|
70
|
-
@s.fragment("a\ufeffbc").must_equal 'abc'
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should strip object replacement characters' do
|
74
|
-
@s.document("a\ufffcbc").must_equal "<html><head></head><body>abc</body></html>\n"
|
75
|
-
@s.fragment("a\ufffcbc").must_equal 'abc'
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'should strip musical notation scoping characters' do
|
79
|
-
@s.document("a\u{1d173}b\u{1d174}c\u{1d175}d\u{1d176}e\u{1d177}f\u{1d178}g\u{1d179}h\u{1d17a}")
|
80
|
-
.must_equal "<html><head></head><body>abcdefgh</body></html>\n"
|
81
|
-
|
82
|
-
@s.fragment("a\u{1d173}b\u{1d174}c\u{1d175}d\u{1d176}e\u{1d177}f\u{1d178}g\u{1d179}h\u{1d17a}")
|
83
|
-
.must_equal 'abcdefgh'
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'should strip language tag code point characters' do
|
87
|
-
str = String.new 'a'
|
88
|
-
(0xE0000..0xE007F).each {|n| str << [n].pack('U') }
|
89
|
-
str << 'b'
|
90
|
-
|
91
|
-
@s.document(str).must_equal "<html><head></head><body>ab</body></html>\n"
|
92
|
-
@s.fragment(str).must_equal 'ab'
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|