@@ -1136,6 +1136,24 @@ def test_should_prune_malignmark
11361136 assert_includes ( acceptable_results , actual )
11371137 end
11381138
1139+ def test_should_prune_noscript
1140+ # https://hackerone.com/reports/2509647
1141+ input , tags = "<div><noscript><p id='</noscript><script>alert(1)</script>'></noscript>" , [ "p" , "div" , "noscript" ]
1142+ actual = nil
1143+ assert_output ( nil , /WARNING: 'noscript' tags cannot be allowed by the PermitScrubber/ ) do
1144+ actual = safe_list_sanitize ( input , tags : tags , attributes : %w( id ) )
1145+ end
1146+
1147+ acceptable_results = [
1148+ # libxml2
1149+ "<div><p id=\" </noscript><script>alert(1)</script>\" ></p></div>" ,
1150+ # libgumbo
1151+ "<div><p id=\" </noscript><script>alert(1)</script>\" ></p></div>" ,
1152+ ]
1153+
1154+ assert_includes ( acceptable_results , actual )
1155+ end
1156+
11391157 protected
11401158 def safe_list_sanitize ( input , options = { } )
11411159 module_under_test ::SafeListSanitizer . new . sanitize ( input , options )
@@ -1247,5 +1265,22 @@ def test_should_not_be_vulnerable_to_malignmark_namespace_confusion
12471265
12481266 assert_nil ( xss )
12491267 end
1268+
1269+ def test_should_not_be_vulnerable_to_noscript_attacks
1270+ # https://hackerone.com/reports/2509647
1271+ skip ( "browser assertion requires parse_noscript_content_as_text" ) unless Nokogiri ::VERSION >= "1.17"
1272+
1273+ input = '<noscript><p id="</noscript><script>alert(1)</script>"></noscript>'
1274+
1275+ result = nil
1276+ assert_output ( nil , /WARNING/ ) do
1277+ result = Rails ::HTML5 ::SafeListSanitizer . new . sanitize ( input , tags : %w( p div noscript ) , attributes : %w( id class style ) )
1278+ end
1279+
1280+ browser = Nokogiri ::HTML5 ::Document . parse ( result , parse_noscript_content_as_text : true )
1281+ xss = browser . at_xpath ( "//script" )
1282+
1283+ assert_nil ( xss )
1284+ end
12501285 end if loofah_html5_support?
12511286end
0 commit comments