@@ -587,23 +587,124 @@ def test_exclude_node_type_comment
587
587
assert_equal ( "<div>text</div><b>text</b>" , safe_list_sanitize ( "<div>text</div><!-- comment --><b>text</b>" ) )
588
588
end
589
589
590
- def test_disallow_the_dangerous_safelist_combination_of_select_and_style
591
- input = "<select><style><script>alert(1)</script></style></select>"
592
- tags = [ "select" , "style" ]
593
- warning = /WARNING: Rails::Html::SafeListSanitizer: removing 'style' from safelist/
594
- sanitized = nil
595
- invocation = Proc . new { sanitized = safe_list_sanitize ( input , tags : tags ) }
596
-
597
- if html5_mode?
598
- # if Loofah is using an HTML5 parser,
599
- # then "style" should be removed by the parser as an invalid child of "select"
600
- assert_silent ( &invocation )
601
- else
602
- # if Loofah is using an HTML4 parser,
603
- # then SafeListSanitizer should remove "style" from the safelist
604
- assert_output ( nil , warning , &invocation )
590
+ %w[ text/plain text/css image/png image/gif image/jpeg ] . each do |mediatype |
591
+ define_method "test_mediatype_#{ mediatype } _allowed" do
592
+ input = %Q(<img src="data:#{ mediatype } ;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
593
+ expected = input
594
+ actual = safe_list_sanitize ( input )
595
+ assert_equal ( expected , actual )
596
+
597
+ input = %Q(<img src="DATA:#{ mediatype } ;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
598
+ expected = input
599
+ actual = safe_list_sanitize ( input )
600
+ assert_equal ( expected , actual )
605
601
end
606
- refute_includes ( sanitized , "style" )
602
+ end
603
+
604
+ def test_mediatype_text_html_disallowed
605
+ input = %q(<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
606
+ expected = %q(<img>)
607
+ actual = safe_list_sanitize ( input )
608
+ assert_equal ( expected , actual )
609
+
610
+ input = %q(<img src="DATA:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
611
+ expected = %q(<img>)
612
+ actual = safe_list_sanitize ( input )
613
+ assert_equal ( expected , actual )
614
+ end
615
+
616
+ def test_mediatype_image_svg_xml_disallowed
617
+ input = %q(<img src="data:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
618
+ expected = %q(<img>)
619
+ actual = safe_list_sanitize ( input )
620
+ assert_equal ( expected , actual )
621
+
622
+ input = %q(<img src="DATA:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
623
+ expected = %q(<img>)
624
+ actual = safe_list_sanitize ( input )
625
+ assert_equal ( expected , actual )
626
+ end
627
+
628
+ def test_mediatype_other_disallowed
629
+ input = %q(<a href="data:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
630
+ expected = %q(<a>foo</a>)
631
+ actual = safe_list_sanitize ( input )
632
+ assert_equal ( expected , actual )
633
+
634
+ input = %q(<a href="DATA:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
635
+ expected = %q(<a>foo</a>)
636
+ actual = safe_list_sanitize ( input )
637
+ assert_equal ( expected , actual )
638
+ end
639
+
640
+ def test_scrubbing_svg_attr_values_that_allow_ref
641
+ input = %Q(<div fill="yellow url(http://bad.com/) #fff">hey</div>)
642
+ expected = %Q(<div fill="yellow #fff">hey</div>)
643
+ actual = scope_allowed_attributes %w( fill ) do
644
+ safe_list_sanitize ( input )
645
+ end
646
+
647
+ assert_equal ( expected , actual )
648
+ end
649
+
650
+ def test_style_with_css_payload
651
+ input , tags = "<style>div > span { background: \" red\" ; }</style>" , [ "style" ]
652
+ expected = "<style>div > span { background: \" red\" ; }</style>"
653
+ actual = safe_list_sanitize ( input , tags : tags )
654
+
655
+ assert_equal ( expected , actual )
656
+ end
657
+
658
+ def test_combination_of_select_and_style_with_css_payload
659
+ input , tags = "<select><style>div > span { background: \" red\" ; }</style></select>" , [ "select" , "style" ]
660
+ expected = "<select><style>div > span { background: \" red\" ; }</style></select>"
661
+ actual = safe_list_sanitize ( input , tags : tags )
662
+
663
+ assert_equal ( expected , actual )
664
+ end
665
+
666
+ def test_combination_of_select_and_style_with_script_payload
667
+ input , tags = "<select><style><script>alert(1)</script></style></select>" , [ "select" , "style" ]
668
+ expected = "<select><style><script>alert(1)</script></style></select>"
669
+ actual = safe_list_sanitize ( input , tags : tags )
670
+
671
+ assert_equal ( expected , actual )
672
+ end
673
+
674
+ def test_combination_of_svg_and_style_with_script_payload
675
+ input , tags = "<svg><style><script>alert(1)</script></style></svg>" , [ "svg" , "style" ]
676
+ expected = "<svg><style><script>alert(1)</script></style></svg>"
677
+ actual = safe_list_sanitize ( input , tags : tags )
678
+
679
+ assert_equal ( expected , actual )
680
+ end
681
+
682
+ def test_combination_of_math_and_style_with_img_payload
683
+ input , tags = "<math><style><img src=x onerror=alert(1)></style></math>" , [ "math" , "style" ]
684
+ expected = "<math><style><img src=x onerror=alert(1)></style></math>"
685
+ actual = safe_list_sanitize ( input , tags : tags )
686
+
687
+ assert_equal ( expected , actual )
688
+
689
+ input , tags = "<math><style><img src=x onerror=alert(1)></style></math>" , [ "math" , "style" , "img" ]
690
+ expected = "<math><style><img src=x onerror=alert(1)></style></math>"
691
+ actual = safe_list_sanitize ( input , tags : tags )
692
+
693
+ assert_equal ( expected , actual )
694
+ end
695
+
696
+ def test_combination_of_svg_and_style_with_img_payload
697
+ input , tags = "<svg><style><img src=x onerror=alert(1)></style></svg>" , [ "svg" , "style" ]
698
+ expected = "<svg><style><img src=x onerror=alert(1)></style></svg>"
699
+ actual = safe_list_sanitize ( input , tags : tags )
700
+
701
+ assert_equal ( expected , actual )
702
+
703
+ input , tags = "<svg><style><img src=x onerror=alert(1)></style></svg>" , [ "svg" , "style" , "img" ]
704
+ expected = "<svg><style><img src=x onerror=alert(1)></style></svg>"
705
+ actual = safe_list_sanitize ( input , tags : tags )
706
+
707
+ assert_equal ( expected , actual )
607
708
end
608
709
609
710
protected
@@ -673,8 +774,4 @@ def libxml_2_9_14_recovery_lt_bang?
673
774
# then reverted in 2.10.0, see https://gitlab.gnome.org/GNOME/libxml2/-/issues/380
674
775
Nokogiri . method ( :uses_libxml? ) . arity == -1 && Nokogiri . uses_libxml? ( "= 2.9.14" )
675
776
end
676
-
677
- def html5_mode?
678
- ::Loofah . respond_to? ( :html5_mode? ) && ::Loofah . html5_mode?
679
- end
680
777
end
0 commit comments