sanitize 6.0.0 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sanitize might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/HISTORY.md +52 -0
- data/README.md +25 -19
- data/lib/sanitize/config/default.rb +5 -0
- data/lib/sanitize/transformers/clean_element.rb +45 -0
- data/lib/sanitize/version.rb +1 -1
- data/test/test_clean_comment.rb +16 -16
- data/test/test_clean_css.rb +5 -5
- data/test/test_clean_doctype.rb +15 -15
- data/test/test_clean_element.rb +99 -92
- data/test/test_config.rb +9 -9
- data/test/test_malicious_css.rb +7 -7
- data/test/test_malicious_html.rb +135 -31
- data/test/test_parser.rb +8 -8
- data/test/test_sanitize.rb +24 -24
- data/test/test_sanitize_css.rb +53 -53
- data/test/test_transformers.rb +37 -37
- metadata +3 -3
data/test/test_clean_element.rb
CHANGED
@@ -163,94 +163,94 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
163
163
|
|
164
164
|
describe 'Default config' do
|
165
165
|
it 'should remove non-allowlisted elements, leaving safe contents behind' do
|
166
|
-
Sanitize.fragment('foo <b>bar</b> <strong><a href="#a">baz</a></strong> quux')
|
166
|
+
_(Sanitize.fragment('foo <b>bar</b> <strong><a href="#a">baz</a></strong> quux'))
|
167
167
|
.must_equal 'foo bar baz quux'
|
168
168
|
|
169
|
-
Sanitize.fragment('<script>alert("<xss>");</script>')
|
169
|
+
_(Sanitize.fragment('<script>alert("<xss>");</script>'))
|
170
170
|
.must_equal ''
|
171
171
|
|
172
|
-
Sanitize.fragment('<<script>script>alert("<xss>");</<script>>')
|
172
|
+
_(Sanitize.fragment('<<script>script>alert("<xss>");</<script>>'))
|
173
173
|
.must_equal '<'
|
174
174
|
|
175
|
-
Sanitize.fragment('< script <>> alert("<xss>");</script>')
|
175
|
+
_(Sanitize.fragment('< script <>> alert("<xss>");</script>'))
|
176
176
|
.must_equal '< script <>> alert("");'
|
177
177
|
end
|
178
178
|
|
179
179
|
it 'should surround the contents of :whitespace_elements with space characters when removing the element' do
|
180
|
-
Sanitize.fragment('foo<div>bar</div>baz')
|
180
|
+
_(Sanitize.fragment('foo<div>bar</div>baz'))
|
181
181
|
.must_equal 'foo bar baz'
|
182
182
|
|
183
|
-
Sanitize.fragment('foo<br>bar<br>baz')
|
183
|
+
_(Sanitize.fragment('foo<br>bar<br>baz'))
|
184
184
|
.must_equal 'foo bar baz'
|
185
185
|
|
186
|
-
Sanitize.fragment('foo<hr>bar<hr>baz')
|
186
|
+
_(Sanitize.fragment('foo<hr>bar<hr>baz'))
|
187
187
|
.must_equal 'foo bar baz'
|
188
188
|
end
|
189
189
|
|
190
190
|
it 'should not choke on several instances of the same element in a row' do
|
191
|
-
Sanitize.fragment('<img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif">')
|
191
|
+
_(Sanitize.fragment('<img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif"><img src="http://www.google.com/intl/en_ALL/images/logo.gif">'))
|
192
192
|
.must_equal ''
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'should not preserve the content of removed `iframe` elements' do
|
196
|
-
Sanitize.fragment('<iframe>hello! <script>alert(0)</script></iframe>')
|
196
|
+
_(Sanitize.fragment('<iframe>hello! <script>alert(0)</script></iframe>'))
|
197
197
|
.must_equal ''
|
198
198
|
end
|
199
199
|
|
200
200
|
it 'should not preserve the content of removed `math` elements' do
|
201
|
-
Sanitize.fragment('<math>hello! <script>alert(0)</script></math>')
|
201
|
+
_(Sanitize.fragment('<math>hello! <script>alert(0)</script></math>'))
|
202
202
|
.must_equal ''
|
203
203
|
end
|
204
204
|
|
205
205
|
it 'should not preserve the content of removed `noembed` elements' do
|
206
|
-
Sanitize.fragment('<noembed>hello! <script>alert(0)</script></noembed>')
|
206
|
+
_(Sanitize.fragment('<noembed>hello! <script>alert(0)</script></noembed>'))
|
207
207
|
.must_equal ''
|
208
208
|
end
|
209
209
|
|
210
210
|
it 'should not preserve the content of removed `noframes` elements' do
|
211
|
-
Sanitize.fragment('<noframes>hello! <script>alert(0)</script></noframes>')
|
211
|
+
_(Sanitize.fragment('<noframes>hello! <script>alert(0)</script></noframes>'))
|
212
212
|
.must_equal ''
|
213
213
|
end
|
214
214
|
|
215
215
|
it 'should not preserve the content of removed `noscript` elements' do
|
216
|
-
Sanitize.fragment('<noscript>hello! <script>alert(0)</script></noscript>')
|
216
|
+
_(Sanitize.fragment('<noscript>hello! <script>alert(0)</script></noscript>'))
|
217
217
|
.must_equal ''
|
218
218
|
end
|
219
219
|
|
220
220
|
it 'should not preserve the content of removed `plaintext` elements' do
|
221
|
-
Sanitize.fragment('<plaintext>hello! <script>alert(0)</script>')
|
221
|
+
_(Sanitize.fragment('<plaintext>hello! <script>alert(0)</script>'))
|
222
222
|
.must_equal ''
|
223
223
|
end
|
224
224
|
|
225
225
|
it 'should not preserve the content of removed `script` elements' do
|
226
|
-
Sanitize.fragment('<script>hello! <script>alert(0)</script></script>')
|
226
|
+
_(Sanitize.fragment('<script>hello! <script>alert(0)</script></script>'))
|
227
227
|
.must_equal ''
|
228
228
|
end
|
229
229
|
|
230
230
|
it 'should not preserve the content of removed `style` elements' do
|
231
|
-
Sanitize.fragment('<style>hello! <script>alert(0)</script></style>')
|
231
|
+
_(Sanitize.fragment('<style>hello! <script>alert(0)</script></style>'))
|
232
232
|
.must_equal ''
|
233
233
|
end
|
234
234
|
|
235
235
|
it 'should not preserve the content of removed `svg` elements' do
|
236
|
-
Sanitize.fragment('<svg>hello! <script>alert(0)</script></svg>')
|
236
|
+
_(Sanitize.fragment('<svg>hello! <script>alert(0)</script></svg>'))
|
237
237
|
.must_equal ''
|
238
238
|
end
|
239
239
|
|
240
240
|
it 'should not preserve the content of removed `xmp` elements' do
|
241
|
-
Sanitize.fragment('<xmp>hello! <script>alert(0)</script></xmp>')
|
241
|
+
_(Sanitize.fragment('<xmp>hello! <script>alert(0)</script></xmp>'))
|
242
242
|
.must_equal ''
|
243
243
|
end
|
244
244
|
|
245
245
|
strings.each do |name, data|
|
246
246
|
it "should clean #{name} HTML" do
|
247
|
-
Sanitize.fragment(data[:html]).must_equal(data[:default])
|
247
|
+
_(Sanitize.fragment(data[:html])).must_equal(data[:default])
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
251
251
|
protocols.each do |name, data|
|
252
252
|
it "should not allow #{name}" do
|
253
|
-
Sanitize.fragment(data[:html]).must_equal(data[:default])
|
253
|
+
_(Sanitize.fragment(data[:html])).must_equal(data[:default])
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
@@ -262,13 +262,13 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
262
262
|
|
263
263
|
strings.each do |name, data|
|
264
264
|
it "should clean #{name} HTML" do
|
265
|
-
@s.fragment(data[:html]).must_equal(data[:restricted])
|
265
|
+
_(@s.fragment(data[:html])).must_equal(data[:restricted])
|
266
266
|
end
|
267
267
|
end
|
268
268
|
|
269
269
|
protocols.each do |name, data|
|
270
270
|
it "should not allow #{name}" do
|
271
|
-
@s.fragment(data[:html]).must_equal(data[:restricted])
|
271
|
+
_(@s.fragment(data[:html])).must_equal(data[:restricted])
|
272
272
|
end
|
273
273
|
end
|
274
274
|
end
|
@@ -279,24 +279,24 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
279
279
|
end
|
280
280
|
|
281
281
|
it 'should not choke on valueless attributes' do
|
282
|
-
@s.fragment('foo <a href>foo</a> bar')
|
282
|
+
_(@s.fragment('foo <a href>foo</a> bar'))
|
283
283
|
.must_equal 'foo <a href="" rel="nofollow">foo</a> bar'
|
284
284
|
end
|
285
285
|
|
286
286
|
it 'should downcase attribute names' do
|
287
|
-
@s.fragment('<a HREF="javascript:alert(\'foo\')">bar</a>')
|
287
|
+
_(@s.fragment('<a HREF="javascript:alert(\'foo\')">bar</a>'))
|
288
288
|
.must_equal '<a rel="nofollow">bar</a>'
|
289
289
|
end
|
290
290
|
|
291
291
|
strings.each do |name, data|
|
292
292
|
it "should clean #{name} HTML" do
|
293
|
-
@s.fragment(data[:html]).must_equal(data[:basic])
|
293
|
+
_(@s.fragment(data[:html])).must_equal(data[:basic])
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
297
297
|
protocols.each do |name, data|
|
298
298
|
it "should not allow #{name}" do
|
299
|
-
@s.fragment(data[:html]).must_equal(data[:basic])
|
299
|
+
_(@s.fragment(data[:html])).must_equal(data[:basic])
|
300
300
|
end
|
301
301
|
end
|
302
302
|
end
|
@@ -307,19 +307,19 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
307
307
|
end
|
308
308
|
|
309
309
|
it 'should encode special chars in attribute values' do
|
310
|
-
@s.fragment('<a href="http://example.com" title="<b>éxamples</b> & things">foo</a>')
|
310
|
+
_(@s.fragment('<a href="http://example.com" title="<b>éxamples</b> & things">foo</a>'))
|
311
311
|
.must_equal '<a href="http://example.com" title="<b>éxamples</b> & things">foo</a>'
|
312
312
|
end
|
313
313
|
|
314
314
|
strings.each do |name, data|
|
315
315
|
it "should clean #{name} HTML" do
|
316
|
-
@s.fragment(data[:html]).must_equal(data[:relaxed])
|
316
|
+
_(@s.fragment(data[:html])).must_equal(data[:relaxed])
|
317
317
|
end
|
318
318
|
end
|
319
319
|
|
320
320
|
protocols.each do |name, data|
|
321
321
|
it "should not allow #{name}" do
|
322
|
-
@s.fragment(data[:html]).must_equal(data[:relaxed])
|
322
|
+
_(@s.fragment(data[:html])).must_equal(data[:relaxed])
|
323
323
|
end
|
324
324
|
end
|
325
325
|
end
|
@@ -328,103 +328,103 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
328
328
|
it 'should allow attributes on all elements if allowlisted under :all' do
|
329
329
|
input = '<p class="foo">bar</p>'
|
330
330
|
|
331
|
-
Sanitize.fragment(input).must_equal ' bar '
|
331
|
+
_(Sanitize.fragment(input)).must_equal ' bar '
|
332
332
|
|
333
|
-
Sanitize.fragment(input, {
|
333
|
+
_(Sanitize.fragment(input, {
|
334
334
|
:elements => ['p'],
|
335
335
|
:attributes => {:all => ['class']}
|
336
|
-
}).must_equal input
|
336
|
+
})).must_equal input
|
337
337
|
|
338
|
-
Sanitize.fragment(input, {
|
338
|
+
_(Sanitize.fragment(input, {
|
339
339
|
:elements => ['p'],
|
340
340
|
:attributes => {'div' => ['class']}
|
341
|
-
}).must_equal '<p>bar</p>'
|
341
|
+
})).must_equal '<p>bar</p>'
|
342
342
|
|
343
|
-
Sanitize.fragment(input, {
|
343
|
+
_(Sanitize.fragment(input, {
|
344
344
|
:elements => ['p'],
|
345
345
|
:attributes => {'p' => ['title'], :all => ['class']}
|
346
|
-
}).must_equal input
|
346
|
+
})).must_equal input
|
347
347
|
end
|
348
348
|
|
349
349
|
it "should not allow relative URLs when relative URLs aren't allowlisted" do
|
350
350
|
input = '<a href="/foo/bar">Link</a>'
|
351
351
|
|
352
|
-
Sanitize.fragment(input,
|
352
|
+
_(Sanitize.fragment(input,
|
353
353
|
:elements => ['a'],
|
354
354
|
:attributes => {'a' => ['href']},
|
355
355
|
:protocols => {'a' => {'href' => ['http']}}
|
356
|
-
).must_equal '<a>Link</a>'
|
356
|
+
)).must_equal '<a>Link</a>'
|
357
357
|
end
|
358
358
|
|
359
359
|
it 'should allow relative URLs containing colons when the colon is not in the first path segment' do
|
360
360
|
input = '<a href="/wiki/Special:Random">Random Page</a>'
|
361
361
|
|
362
|
-
Sanitize.fragment(input, {
|
362
|
+
_(Sanitize.fragment(input, {
|
363
363
|
:elements => ['a'],
|
364
364
|
:attributes => {'a' => ['href']},
|
365
365
|
:protocols => {'a' => {'href' => [:relative]}}
|
366
|
-
}).must_equal input
|
366
|
+
})).must_equal input
|
367
367
|
end
|
368
368
|
|
369
369
|
it 'should allow relative URLs containing colons when the colon is part of an anchor' do
|
370
370
|
input = '<a href="#fn:1">Footnote 1</a>'
|
371
371
|
|
372
|
-
Sanitize.fragment(input, {
|
372
|
+
_(Sanitize.fragment(input, {
|
373
373
|
:elements => ['a'],
|
374
374
|
:attributes => {'a' => ['href']},
|
375
375
|
:protocols => {'a' => {'href' => [:relative]}}
|
376
|
-
}).must_equal input
|
376
|
+
})).must_equal input
|
377
377
|
|
378
378
|
input = '<a href="somepage#fn:1">Footnote 1</a>'
|
379
379
|
|
380
|
-
Sanitize.fragment(input, {
|
380
|
+
_(Sanitize.fragment(input, {
|
381
381
|
:elements => ['a'],
|
382
382
|
:attributes => {'a' => ['href']},
|
383
383
|
:protocols => {'a' => {'href' => [:relative]}}
|
384
|
-
}).must_equal input
|
384
|
+
})).must_equal input
|
385
385
|
end
|
386
386
|
|
387
387
|
it 'should remove the contents of filtered nodes when :remove_contents is true' do
|
388
|
-
Sanitize.fragment('foo bar <div>baz<span>quux</span></div>',
|
388
|
+
_(Sanitize.fragment('foo bar <div>baz<span>quux</span></div>',
|
389
389
|
:remove_contents => true
|
390
|
-
).must_equal 'foo bar '
|
390
|
+
)).must_equal 'foo bar '
|
391
391
|
end
|
392
392
|
|
393
393
|
it 'should remove the contents of specified nodes when :remove_contents is an Array or Set of element names as strings' do
|
394
|
-
Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
394
|
+
_(Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
395
395
|
:remove_contents => ['script', 'span']
|
396
|
-
).must_equal 'foo bar baz hi '
|
396
|
+
)).must_equal 'foo bar baz hi '
|
397
397
|
|
398
|
-
Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
398
|
+
_(Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
399
399
|
:remove_contents => Set.new(['script', 'span'])
|
400
|
-
).must_equal 'foo bar baz hi '
|
400
|
+
)).must_equal 'foo bar baz hi '
|
401
401
|
end
|
402
402
|
|
403
403
|
it 'should remove the contents of specified nodes when :remove_contents is an Array or Set of element names as symbols' do
|
404
|
-
Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
404
|
+
_(Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
405
405
|
:remove_contents => [:script, :span]
|
406
|
-
).must_equal 'foo bar baz hi '
|
406
|
+
)).must_equal 'foo bar baz hi '
|
407
407
|
|
408
|
-
Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
408
|
+
_(Sanitize.fragment('foo bar <div>baz<span>quux</span> <b>hi</b><script>alert("hello!");</script></div>',
|
409
409
|
:remove_contents => Set.new([:script, :span])
|
410
|
-
).must_equal 'foo bar baz hi '
|
410
|
+
)).must_equal 'foo bar baz hi '
|
411
411
|
end
|
412
412
|
|
413
413
|
it 'should remove the contents of allowlisted iframes' do
|
414
|
-
Sanitize.fragment('<iframe>hi <script>hello</script></iframe>',
|
414
|
+
_(Sanitize.fragment('<iframe>hi <script>hello</script></iframe>',
|
415
415
|
:elements => ['iframe']
|
416
|
-
).must_equal '<iframe></iframe>'
|
416
|
+
)).must_equal '<iframe></iframe>'
|
417
417
|
end
|
418
418
|
|
419
419
|
it 'should not allow arbitrary HTML5 data attributes by default' do
|
420
|
-
Sanitize.fragment('<b data-foo="bar"></b>',
|
420
|
+
_(Sanitize.fragment('<b data-foo="bar"></b>',
|
421
421
|
:elements => ['b']
|
422
|
-
).must_equal '<b></b>'
|
422
|
+
)).must_equal '<b></b>'
|
423
423
|
|
424
|
-
Sanitize.fragment('<b class="foo" data-foo="bar"></b>',
|
424
|
+
_(Sanitize.fragment('<b class="foo" data-foo="bar"></b>',
|
425
425
|
:attributes => {'b' => ['class']},
|
426
426
|
:elements => ['b']
|
427
|
-
).must_equal '<b class="foo"></b>'
|
427
|
+
)).must_equal '<b class="foo"></b>'
|
428
428
|
end
|
429
429
|
|
430
430
|
it 'should allow arbitrary HTML5 data attributes when the :attributes config includes :data' do
|
@@ -433,28 +433,28 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
433
433
|
:elements => ['b']
|
434
434
|
)
|
435
435
|
|
436
|
-
s.fragment('<b data-foo="valid" data-bar="valid"></b>')
|
436
|
+
_(s.fragment('<b data-foo="valid" data-bar="valid"></b>'))
|
437
437
|
.must_equal '<b data-foo="valid" data-bar="valid"></b>'
|
438
438
|
|
439
|
-
s.fragment('<b data-="invalid"></b>')
|
439
|
+
_(s.fragment('<b data-="invalid"></b>'))
|
440
440
|
.must_equal '<b></b>'
|
441
441
|
|
442
|
-
s.fragment('<b data-="invalid"></b>')
|
442
|
+
_(s.fragment('<b data-="invalid"></b>'))
|
443
443
|
.must_equal '<b></b>'
|
444
444
|
|
445
|
-
s.fragment('<b data-xml="invalid"></b>')
|
445
|
+
_(s.fragment('<b data-xml="invalid"></b>'))
|
446
446
|
.must_equal '<b></b>'
|
447
447
|
|
448
|
-
s.fragment('<b data-xmlfoo="invalid"></b>')
|
448
|
+
_(s.fragment('<b data-xmlfoo="invalid"></b>'))
|
449
449
|
.must_equal '<b></b>'
|
450
450
|
|
451
|
-
s.fragment('<b data-f:oo="valid"></b>')
|
451
|
+
_(s.fragment('<b data-f:oo="valid"></b>'))
|
452
452
|
.must_equal '<b></b>'
|
453
453
|
|
454
|
-
s.fragment('<b data-f/oo="partial"></b>')
|
454
|
+
_(s.fragment('<b data-f/oo="partial"></b>'))
|
455
455
|
.must_equal '<b data-f=""></b>' # Nokogiri quirk; not ideal, but harmless
|
456
456
|
|
457
|
-
s.fragment('<b data-éfoo="valid"></b>')
|
457
|
+
_(s.fragment('<b data-éfoo="valid"></b>'))
|
458
458
|
.must_equal '<b></b>' # Another annoying Nokogiri quirk.
|
459
459
|
end
|
460
460
|
|
@@ -467,78 +467,85 @@ describe 'Sanitize::Transformers::CleanElement' do
|
|
467
467
|
}
|
468
468
|
)
|
469
469
|
|
470
|
-
s.fragment('<p>foo</p>').must_equal "\nfoo\n"
|
471
|
-
s.fragment('<p>foo</p><p>bar</p>').must_equal "\nfoo\n\nbar\n"
|
472
|
-
s.fragment('foo<div>bar</div>baz').must_equal "foo\nbar\nbaz"
|
473
|
-
s.fragment('foo<br>bar<br>baz').must_equal "foo\nbar\nbaz"
|
470
|
+
_(s.fragment('<p>foo</p>')).must_equal "\nfoo\n"
|
471
|
+
_(s.fragment('<p>foo</p><p>bar</p>')).must_equal "\nfoo\n\nbar\n"
|
472
|
+
_(s.fragment('foo<div>bar</div>baz')).must_equal "foo\nbar\nbaz"
|
473
|
+
_(s.fragment('foo<br>bar<br>baz')).must_equal "foo\nbar\nbaz"
|
474
474
|
end
|
475
475
|
|
476
476
|
it 'should handle protocols correctly regardless of case' do
|
477
477
|
input = '<a href="hTTpS://foo.com/">Text</a>'
|
478
478
|
|
479
|
-
Sanitize.fragment(input, {
|
479
|
+
_(Sanitize.fragment(input, {
|
480
480
|
:elements => ['a'],
|
481
481
|
:attributes => {'a' => ['href']},
|
482
482
|
:protocols => {'a' => {'href' => ['https']}}
|
483
|
-
}).must_equal input
|
483
|
+
})).must_equal input
|
484
484
|
|
485
485
|
input = '<a href="mailto:someone@example.com?Subject=Hello">Text</a>'
|
486
486
|
|
487
|
-
Sanitize.fragment(input, {
|
487
|
+
_(Sanitize.fragment(input, {
|
488
488
|
:elements => ['a'],
|
489
489
|
:attributes => {'a' => ['href']},
|
490
490
|
:protocols => {'a' => {'href' => ['https']}}
|
491
|
-
}).must_equal "<a>Text</a>"
|
491
|
+
})).must_equal "<a>Text</a>"
|
492
492
|
end
|
493
493
|
|
494
494
|
it 'should sanitize protocols in data attributes even if data attributes are generically allowed' do
|
495
495
|
input = '<a data-url="mailto:someone@example.com">Text</a>'
|
496
496
|
|
497
|
-
Sanitize.fragment(input, {
|
497
|
+
_(Sanitize.fragment(input, {
|
498
498
|
:elements => ['a'],
|
499
499
|
:attributes => {'a' => [:data]},
|
500
500
|
:protocols => {'a' => {'data-url' => ['https']}}
|
501
|
-
}).must_equal "<a>Text</a>"
|
501
|
+
})).must_equal "<a>Text</a>"
|
502
502
|
|
503
|
-
Sanitize.fragment(input, {
|
503
|
+
_(Sanitize.fragment(input, {
|
504
504
|
:elements => ['a'],
|
505
505
|
:attributes => {'a' => [:data]},
|
506
506
|
:protocols => {'a' => {'data-url' => ['mailto']}}
|
507
|
-
}).must_equal input
|
507
|
+
})).must_equal input
|
508
508
|
end
|
509
509
|
|
510
510
|
it 'should prevent `<meta>` tags from being used to set a non-UTF-8 charset' do
|
511
|
-
Sanitize.document('<html><head><meta charset="utf-8"></head><body>Howdy!</body></html>',
|
511
|
+
_(Sanitize.document('<html><head><meta charset="utf-8"></head><body>Howdy!</body></html>',
|
512
512
|
:elements => %w[html head meta body],
|
513
513
|
:attributes => {'meta' => ['charset']}
|
514
|
-
).must_equal "<html><head><meta charset=\"utf-8\"></head><body>Howdy!</body></html>"
|
514
|
+
)).must_equal "<html><head><meta charset=\"utf-8\"></head><body>Howdy!</body></html>"
|
515
515
|
|
516
|
-
Sanitize.document('<html><meta charset="utf-8">Howdy!</html>',
|
516
|
+
_(Sanitize.document('<html><meta charset="utf-8">Howdy!</html>',
|
517
517
|
:elements => %w[html meta],
|
518
518
|
:attributes => {'meta' => ['charset']}
|
519
|
-
).must_equal "<html><meta charset=\"utf-8\">Howdy!</html>"
|
519
|
+
)).must_equal "<html><meta charset=\"utf-8\">Howdy!</html>"
|
520
520
|
|
521
|
-
Sanitize.document('<html><meta charset="us-ascii">Howdy!</html>',
|
521
|
+
_(Sanitize.document('<html><meta charset="us-ascii">Howdy!</html>',
|
522
522
|
:elements => %w[html meta],
|
523
523
|
:attributes => {'meta' => ['charset']}
|
524
|
-
).must_equal "<html><meta charset=\"utf-8\">Howdy!</html>"
|
524
|
+
)).must_equal "<html><meta charset=\"utf-8\">Howdy!</html>"
|
525
525
|
|
526
|
-
Sanitize.document('<html><meta http-equiv="content-type" content=" text/html; charset=us-ascii">Howdy!</html>',
|
526
|
+
_(Sanitize.document('<html><meta http-equiv="content-type" content=" text/html; charset=us-ascii">Howdy!</html>',
|
527
527
|
:elements => %w[html meta],
|
528
528
|
:attributes => {'meta' => %w[content http-equiv]}
|
529
|
-
).must_equal "<html><meta http-equiv=\"content-type\" content=\" text/html;charset=utf-8\">Howdy!</html>"
|
529
|
+
)).must_equal "<html><meta http-equiv=\"content-type\" content=\" text/html;charset=utf-8\">Howdy!</html>"
|
530
530
|
|
531
|
-
Sanitize.document('<html><meta http-equiv="Content-Type" content="text/plain;charset = us-ascii">Howdy!</html>',
|
531
|
+
_(Sanitize.document('<html><meta http-equiv="Content-Type" content="text/plain;charset = us-ascii">Howdy!</html>',
|
532
532
|
:elements => %w[html meta],
|
533
533
|
:attributes => {'meta' => %w[content http-equiv]}
|
534
|
-
).must_equal "<html><meta http-equiv=\"Content-Type\" content=\"text/plain;charset=utf-8\">Howdy!</html>"
|
534
|
+
)).must_equal "<html><meta http-equiv=\"Content-Type\" content=\"text/plain;charset=utf-8\">Howdy!</html>"
|
535
535
|
end
|
536
536
|
|
537
537
|
it 'should not modify `<meta>` tags that already set a UTF-8 charset' do
|
538
|
-
Sanitize.document('<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"></head><body>Howdy!</body></html>',
|
538
|
+
_(Sanitize.document('<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"></head><body>Howdy!</body></html>',
|
539
539
|
:elements => %w[html head meta body],
|
540
540
|
:attributes => {'meta' => %w[content http-equiv]}
|
541
|
-
).must_equal "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"></head><body>Howdy!</body></html>"
|
541
|
+
)).must_equal "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"></head><body>Howdy!</body></html>"
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'always removes `<noscript>` elements even if `noscript` is in the allowlist' do
|
545
|
+
assert_equal(
|
546
|
+
'',
|
547
|
+
Sanitize.fragment('<noscript>foo</noscript>', elements: ['noscript'])
|
548
|
+
)
|
542
549
|
end
|
543
550
|
|
544
551
|
end
|
data/test/test_config.rb
CHANGED
@@ -6,7 +6,7 @@ describe 'Config' do
|
|
6
6
|
parallelize_me!
|
7
7
|
|
8
8
|
def verify_deeply_frozen(config)
|
9
|
-
config.must_be :frozen?
|
9
|
+
_(config).must_be :frozen?
|
10
10
|
|
11
11
|
if Hash === config
|
12
12
|
config.each_value {|v| verify_deeply_frozen(v) }
|
@@ -27,7 +27,7 @@ describe 'Config' do
|
|
27
27
|
a = {:one => {:one_one => [0, '1', :a], :one_two => false, :one_three => Set.new([:a, :b, :c])}}
|
28
28
|
b = Sanitize::Config.freeze_config(a)
|
29
29
|
|
30
|
-
b.must_be_same_as a
|
30
|
+
_(b).must_be_same_as a
|
31
31
|
verify_deeply_frozen a
|
32
32
|
end
|
33
33
|
end
|
@@ -40,10 +40,10 @@ describe 'Config' do
|
|
40
40
|
|
41
41
|
c = Sanitize::Config.merge(a, b)
|
42
42
|
|
43
|
-
c.wont_be_same_as a
|
44
|
-
c.wont_be_same_as b
|
43
|
+
_(c).wont_be_same_as a
|
44
|
+
_(c).wont_be_same_as b
|
45
45
|
|
46
|
-
c.must_equal(
|
46
|
+
_(c).must_equal(
|
47
47
|
:one => {
|
48
48
|
:one_one => [0, '1', :a],
|
49
49
|
:one_two => true,
|
@@ -53,13 +53,13 @@ describe 'Config' do
|
|
53
53
|
:two => 2
|
54
54
|
)
|
55
55
|
|
56
|
-
c[:one].wont_be_same_as a[:one]
|
57
|
-
c[:one][:one_one].wont_be_same_as a[:one][:one_one]
|
56
|
+
_(c[:one]).wont_be_same_as a[:one]
|
57
|
+
_(c[:one][:one_one]).wont_be_same_as a[:one][:one_one]
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'should raise an ArgumentError if either argument is not a Hash' do
|
61
|
-
proc { Sanitize::Config.merge('foo', {}) }.must_raise ArgumentError
|
62
|
-
proc { Sanitize::Config.merge({}, 'foo') }.must_raise ArgumentError
|
61
|
+
_(proc { Sanitize::Config.merge('foo', {}) }).must_raise ArgumentError
|
62
|
+
_(proc { Sanitize::Config.merge({}, 'foo') }).must_raise ArgumentError
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
data/test/test_malicious_css.rb
CHANGED
@@ -16,27 +16,27 @@ describe 'Malicious CSS' do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should not be possible to inject an expression by munging it with a comment' do
|
19
|
-
@s.properties(%[width:expr/*XSS*/ession(alert('XSS'))]).
|
19
|
+
_(@s.properties(%[width:expr/*XSS*/ession(alert('XSS'))])).
|
20
20
|
must_equal ''
|
21
21
|
|
22
|
-
@s.properties(%[width:ex/*XSS*//*/*/pression(alert("XSS"))]).
|
22
|
+
_(@s.properties(%[width:ex/*XSS*//*/*/pression(alert("XSS"))])).
|
23
23
|
must_equal ''
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should not be possible to inject an expression by munging it with a newline' do
|
27
|
-
@s.properties(%[width:\nexpression(alert('XSS'));]).
|
27
|
+
_(@s.properties(%[width:\nexpression(alert('XSS'));])).
|
28
28
|
must_equal ''
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'should not allow the javascript protocol' do
|
32
|
-
@s.properties(%[background-image:url("javascript:alert('XSS')");]).
|
32
|
+
_(@s.properties(%[background-image:url("javascript:alert('XSS')");])).
|
33
33
|
must_equal ''
|
34
34
|
|
35
|
-
Sanitize.fragment(%[<div style="background-image: url(javascript:alert('XSS'))">],
|
36
|
-
Sanitize::Config::RELAXED).must_equal '<div></div>'
|
35
|
+
_(Sanitize.fragment(%[<div style="background-image: url(javascript:alert('XSS'))">],
|
36
|
+
Sanitize::Config::RELAXED)).must_equal '<div></div>'
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should not allow behaviors' do
|
40
|
-
@s.properties(%[behavior: url(xss.htc);]).must_equal ''
|
40
|
+
_(@s.properties(%[behavior: url(xss.htc);])).must_equal ''
|
41
41
|
end
|
42
42
|
end
|