Skip to content

Commit 2191bfe

Browse files
authored
Merge pull request #87 from JuanitoFatas/migrate-to-safelist
Migrate to SafeListSanitizer
2 parents 5b73a09 + 41b0b49 commit 2191bfe

File tree

4 files changed

+77
-66
lines changed

4 files changed

+77
-66
lines changed

README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ link_sanitizer.sanitize('<a href="example.com">Only the link text will be kept.<
4141
# => Only the link text will be kept.
4242
```
4343

44-
#### WhiteListSanitizer
44+
#### SafeListSanitizer
4545

4646
```ruby
47-
white_list_sanitizer = Rails::Html::WhiteListSanitizer.new
47+
safe_list_sanitizer = Rails::Html::SafeListSanitizer.new
4848

49-
# sanitize via an extensive white list of allowed elements
50-
white_list_sanitizer.sanitize(@article.body)
49+
# sanitize via an extensive safe list of allowed elements
50+
safe_list_sanitizer.sanitize(@article.body)
5151

52-
# white list only the supplied tags and attributes
53-
white_list_sanitizer.sanitize(@article.body, tags: %w(table tr td), attributes: %w(id class style))
52+
# safe list only the supplied tags and attributes
53+
safe_list_sanitizer.sanitize(@article.body, tags: %w(table tr td), attributes: %w(id class style))
5454

55-
# white list via a custom scrubber
56-
white_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
55+
# safe list via a custom scrubber
56+
safe_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
5757

58-
# white list sanitizer can also sanitize css
59-
white_list_sanitizer.sanitize_css('background-color: #000;')
58+
# safe list sanitizer can also sanitize css
59+
safe_list_sanitizer.sanitize_css('background-color: #000;')
6060
```
6161

6262
### Scrubbers

lib/rails-html-sanitizer.rb

+9-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ def link_sanitizer
1515
Html::LinkSanitizer
1616
end
1717

18+
def safe_list_sanitizer
19+
Html::SafeListSanitizer
20+
end
21+
1822
def white_list_sanitizer
19-
Html::WhiteListSanitizer
23+
ActiveSupport::Deprecation.warn "warning: white_list_sanitizer is" \
24+
"deprecated, please use safe_list_sanitizer instead."
25+
safe_list_sanitizer
2026
end
2127
end
2228
end
@@ -34,7 +40,7 @@ module ClassMethods
3440
# end
3541
#
3642
def sanitized_allowed_tags=(tags)
37-
sanitizer_vendor.white_list_sanitizer.allowed_tags = tags
43+
sanitizer_vendor.safe_list_sanitizer.allowed_tags = tags
3844
end
3945

4046
# Replaces the allowed HTML attributes for the +sanitize+ helper.
@@ -44,7 +50,7 @@ def sanitized_allowed_tags=(tags)
4450
# end
4551
#
4652
def sanitized_allowed_attributes=(attributes)
47-
sanitizer_vendor.white_list_sanitizer.allowed_attributes = attributes
53+
sanitizer_vendor.safe_list_sanitizer.allowed_attributes = attributes
4854
end
4955

5056
[:protocol_separator,

lib/rails/html/sanitizer.rb

+22-17
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ def sanitize(html, options = {})
5757
end
5858
end
5959

60-
# === Rails::Html::WhiteListSanitizer
61-
# Sanitizes html and css from an extensive white list (see link further down).
60+
# === Rails::Html::SafeListSanitizer
61+
# Sanitizes html and css from an extensive safe list (see link further down).
6262
#
6363
# === Whitespace
6464
# We can't make any guarantees about whitespace being kept or stripped.
@@ -72,34 +72,34 @@ def sanitize(html, options = {})
7272
# so automatically.
7373
#
7474
# === Options
75-
# Sanitizes both html and css via the white lists found here:
75+
# Sanitizes both html and css via the safe lists found here:
7676
# https://github.com/flavorjones/loofah/blob/master/lib/loofah/html5/whitelist.rb
7777
#
78-
# WhiteListSanitizer also accepts options to configure
79-
# the white list used when sanitizing html.
78+
# SafeListSanitizer also accepts options to configure
79+
# the safe list used when sanitizing html.
8080
# There's a class level option:
81-
# Rails::Html::WhiteListSanitizer.allowed_tags = %w(table tr td)
82-
# Rails::Html::WhiteListSanitizer.allowed_attributes = %w(id class style)
81+
# Rails::Html::SafeListSanitizer.allowed_tags = %w(table tr td)
82+
# Rails::Html::SafeListSanitizer.allowed_attributes = %w(id class style)
8383
#
8484
# Tags and attributes can also be passed to +sanitize+.
8585
# Passed options take precedence over the class level options.
8686
#
8787
# === Examples
88-
# white_list_sanitizer = Rails::Html::WhiteListSanitizer.new
88+
# safe_list_sanitizer = Rails::Html::SafeListSanitizer.new
8989
#
9090
# Sanitize css doesn't take options
91-
# white_list_sanitizer.sanitize_css('background-color: #000;')
91+
# safe_list_sanitizer.sanitize_css('background-color: #000;')
9292
#
93-
# Default: sanitize via a extensive white list of allowed elements
94-
# white_list_sanitizer.sanitize(@article.body)
93+
# Default: sanitize via a extensive safe list of allowed elements
94+
# safe_list_sanitizer.sanitize(@article.body)
9595
#
96-
# White list via the supplied tags and attributes
97-
# white_list_sanitizer.sanitize(@article.body, tags: %w(table tr td),
96+
# Safe list via the supplied tags and attributes
97+
# safe_list_sanitizer.sanitize(@article.body, tags: %w(table tr td),
9898
# attributes: %w(id class style))
9999
#
100-
# White list via a custom scrubber
101-
# white_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
102-
class WhiteListSanitizer < Sanitizer
100+
# Safe list via a custom scrubber
101+
# safe_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
102+
class SafeListSanitizer < Sanitizer
103103
class << self
104104
attr_accessor :allowed_tags
105105
attr_accessor :allowed_attributes
@@ -146,7 +146,12 @@ def allowed_tags(options)
146146

147147
def allowed_attributes(options)
148148
options[:attributes] || self.class.allowed_attributes
149-
end
149+
end
150+
end
151+
152+
WhiteListSanitizer = SafeListSanitizer
153+
if Object.respond_to?(:deprecate_constant)
154+
deprecate_constant :WhiteListSanitizer
150155
end
151156
end
152157
end

test/sanitizer_test.rb

+36-36
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ def test_sanitizer_sanitize_raises_not_implemented_error
1212
end
1313

1414
def test_sanitize_nested_script
15-
sanitizer = Rails::Html::WhiteListSanitizer.new
15+
sanitizer = Rails::Html::SafeListSanitizer.new
1616
assert_equal '&lt;script&gt;alert("XSS");&lt;/script&gt;', sanitizer.sanitize('<script><script></script>alert("XSS");<script><</script>/</script><script>script></script>', tags: %w(em))
1717
end
1818

1919
def test_sanitize_nested_script_in_style
20-
sanitizer = Rails::Html::WhiteListSanitizer.new
20+
sanitizer = Rails::Html::SafeListSanitizer.new
2121
assert_equal '&lt;script&gt;alert("XSS");&lt;/script&gt;', sanitizer.sanitize('<style><script></style>alert("XSS");<style><</style>/</style><style>script></style>', tags: %w(em))
2222
end
2323

@@ -255,38 +255,38 @@ def test_custom_attributes_overrides_allowed_attributes
255255

256256
def test_should_allow_custom_tags
257257
text = "<u>foo</u>"
258-
assert_equal text, white_list_sanitize(text, tags: %w(u))
258+
assert_equal text, safe_list_sanitize(text, tags: %w(u))
259259
end
260260

261261
def test_should_allow_only_custom_tags
262262
text = "<u>foo</u> with <i>bar</i>"
263-
assert_equal "<u>foo</u> with bar", white_list_sanitize(text, tags: %w(u))
263+
assert_equal "<u>foo</u> with bar", safe_list_sanitize(text, tags: %w(u))
264264
end
265265

266266
def test_should_allow_custom_tags_with_attributes
267267
text = %(<blockquote cite="http://example.com/">foo</blockquote>)
268-
assert_equal text, white_list_sanitize(text)
268+
assert_equal text, safe_list_sanitize(text)
269269
end
270270

271271
def test_should_allow_custom_tags_with_custom_attributes
272272
text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
273-
assert_equal text, white_list_sanitize(text, attributes: ['foo'])
273+
assert_equal text, safe_list_sanitize(text, attributes: ['foo'])
274274
end
275275

276276
def test_scrub_style_if_style_attribute_option_is_passed
277277
input = '<p style="color: #000; background-image: url(http://www.ragingplatypus.com/i/cam-full.jpg);"></p>'
278-
assert_equal '<p style="color: #000;"></p>', white_list_sanitize(input, attributes: %w(style))
278+
assert_equal '<p style="color: #000;"></p>', safe_list_sanitize(input, attributes: %w(style))
279279
end
280280

281281
def test_should_raise_argument_error_if_tags_is_not_enumerable
282282
assert_raises ArgumentError do
283-
white_list_sanitize('<a>some html</a>', tags: 'foo')
283+
safe_list_sanitize('<a>some html</a>', tags: 'foo')
284284
end
285285
end
286286

287287
def test_should_raise_argument_error_if_attributes_is_not_enumerable
288288
assert_raises ArgumentError do
289-
white_list_sanitize('<a>some html</a>', attributes: 'foo')
289+
safe_list_sanitize('<a>some html</a>', attributes: 'foo')
290290
end
291291
end
292292

@@ -295,7 +295,7 @@ def test_should_not_accept_non_loofah_inheriting_scrubber
295295
def scrubber.scrub(node); node.name = 'h1'; end
296296

297297
assert_raises Loofah::ScrubberNotFound do
298-
white_list_sanitize('<a>some html</a>', scrubber: scrubber)
298+
safe_list_sanitize('<a>some html</a>', scrubber: scrubber)
299299
end
300300
end
301301

@@ -304,19 +304,19 @@ def test_should_accept_loofah_inheriting_scrubber
304304
def scrubber.scrub(node); node.name = 'h1'; end
305305

306306
html = "<script>hello!</script>"
307-
assert_equal "<h1>hello!</h1>", white_list_sanitize(html, scrubber: scrubber)
307+
assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber)
308308
end
309309

310310
def test_should_accept_loofah_scrubber_that_wraps_a_block
311311
scrubber = Loofah::Scrubber.new { |node| node.name = 'h1' }
312312
html = "<script>hello!</script>"
313-
assert_equal "<h1>hello!</h1>", white_list_sanitize(html, scrubber: scrubber)
313+
assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber)
314314
end
315315

316316
def test_custom_scrubber_takes_precedence_over_other_options
317317
scrubber = Loofah::Scrubber.new { |node| node.name = 'h1' }
318318
html = "<script>hello!</script>"
319-
assert_equal "<h1>hello!</h1>", white_list_sanitize(html, scrubber: scrubber, tags: ['foo'])
319+
assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber, tags: ['foo'])
320320
end
321321

322322
[%w(img src), %w(a href)].each do |(tag, attr)|
@@ -468,7 +468,7 @@ def test_x03a_legitimate
468468
end
469469

470470
def test_sanitize_ascii_8bit_string
471-
white_list_sanitize('<a>hello</a>'.encode('ASCII-8BIT')).tap do |sanitized|
471+
safe_list_sanitize('<a>hello</a>'.encode('ASCII-8BIT')).tap do |sanitized|
472472
assert_equal '<a>hello</a>', sanitized
473473
assert_equal Encoding::UTF_8, sanitized.encoding
474474
end
@@ -481,45 +481,45 @@ def test_sanitize_data_attributes
481481

482482
def test_allow_data_attribute_if_requested
483483
text = %(<a data-foo="foo">foo</a>)
484-
assert_equal %(<a data-foo="foo">foo</a>), white_list_sanitize(text, attributes: ['data-foo'])
484+
assert_equal %(<a data-foo="foo">foo</a>), safe_list_sanitize(text, attributes: ['data-foo'])
485485
end
486486

487-
def test_uri_escaping_of_href_attr_in_a_tag_in_white_list_sanitizer
487+
def test_uri_escaping_of_href_attr_in_a_tag_in_safe_list_sanitizer
488488
skip if RUBY_VERSION < "2.3"
489489

490490
html = %{<a href='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
491491

492-
text = white_list_sanitize(html)
492+
text = safe_list_sanitize(html)
493493

494494
assert_equal %{<a href=\"examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com\">test</a>}, text
495495
end
496496

497-
def test_uri_escaping_of_src_attr_in_a_tag_in_white_list_sanitizer
497+
def test_uri_escaping_of_src_attr_in_a_tag_in_safe_list_sanitizer
498498
skip if RUBY_VERSION < "2.3"
499499

500500
html = %{<a src='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
501501

502-
text = white_list_sanitize(html)
502+
text = safe_list_sanitize(html)
503503

504504
assert_equal %{<a src=\"examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com\">test</a>}, text
505505
end
506506

507-
def test_uri_escaping_of_name_attr_in_a_tag_in_white_list_sanitizer
507+
def test_uri_escaping_of_name_attr_in_a_tag_in_safe_list_sanitizer
508508
skip if RUBY_VERSION < "2.3"
509509

510510
html = %{<a name='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
511511

512-
text = white_list_sanitize(html)
512+
text = safe_list_sanitize(html)
513513

514514
assert_equal %{<a name=\"examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com\">test</a>}, text
515515
end
516516

517-
def test_uri_escaping_of_name_action_in_a_tag_in_white_list_sanitizer
517+
def test_uri_escaping_of_name_action_in_a_tag_in_safe_list_sanitizer
518518
skip if RUBY_VERSION < "2.3"
519519

520520
html = %{<a action='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
521521

522-
text = white_list_sanitize(html, attributes: ['action'])
522+
text = safe_list_sanitize(html, attributes: ['action'])
523523

524524
assert_equal %{<a action=\"examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com\">test</a>}, text
525525
end
@@ -538,35 +538,35 @@ def link_sanitize(input, options = {})
538538
Rails::Html::LinkSanitizer.new.sanitize(input, options)
539539
end
540540

541-
def white_list_sanitize(input, options = {})
542-
Rails::Html::WhiteListSanitizer.new.sanitize(input, options)
541+
def safe_list_sanitize(input, options = {})
542+
Rails::Html::SafeListSanitizer.new.sanitize(input, options)
543543
end
544544

545545
def assert_sanitized(input, expected = nil)
546546
if input
547-
assert_dom_equal expected || input, white_list_sanitize(input)
547+
assert_dom_equal expected || input, safe_list_sanitize(input)
548548
else
549-
assert_nil white_list_sanitize(input)
549+
assert_nil safe_list_sanitize(input)
550550
end
551551
end
552552

553553
def sanitize_css(input)
554-
Rails::Html::WhiteListSanitizer.new.sanitize_css(input)
554+
Rails::Html::SafeListSanitizer.new.sanitize_css(input)
555555
end
556556

557557
def scope_allowed_tags(tags)
558-
old_tags = Rails::Html::WhiteListSanitizer.allowed_tags
559-
Rails::Html::WhiteListSanitizer.allowed_tags = tags
560-
yield Rails::Html::WhiteListSanitizer.new
558+
old_tags = Rails::Html::SafeListSanitizer.allowed_tags
559+
Rails::Html::SafeListSanitizer.allowed_tags = tags
560+
yield Rails::Html::SafeListSanitizer.new
561561
ensure
562-
Rails::Html::WhiteListSanitizer.allowed_tags = old_tags
562+
Rails::Html::SafeListSanitizer.allowed_tags = old_tags
563563
end
564564

565565
def scope_allowed_attributes(attributes)
566-
old_attributes = Rails::Html::WhiteListSanitizer.allowed_attributes
567-
Rails::Html::WhiteListSanitizer.allowed_attributes = attributes
568-
yield Rails::Html::WhiteListSanitizer.new
566+
old_attributes = Rails::Html::SafeListSanitizer.allowed_attributes
567+
Rails::Html::SafeListSanitizer.allowed_attributes = attributes
568+
yield Rails::Html::SafeListSanitizer.new
569569
ensure
570-
Rails::Html::WhiteListSanitizer.allowed_attributes = old_attributes
570+
Rails::Html::SafeListSanitizer.allowed_attributes = old_attributes
571571
end
572572
end

0 commit comments

Comments
 (0)