rails-html-sanitizer 1.6.0 → 1.6.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +0 -4
- data/lib/rails/html/sanitizer/version.rb +1 -1
- data/lib/rails/html/sanitizer.rb +1 -0
- data/lib/rails/html/scrubbers.rb +31 -7
- data/test/sanitizer_test.rb +208 -9
- data/test/scrubbers_test.rb +80 -2
- metadata +67 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad86488f25943fb1d0050513a08581231534a8552e4de66329270845ff650b12
|
4
|
+
data.tar.gz: ca70b518cc54e0ec2e224a5c3dbd82d567e39fd2d2ce3538e308f4d8846234b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6e2db01e0cd52d3bdcae7ceb90a081998111e84f19f4908d73a9b229a0ec87edfc10f05772b057d2c3e6c9cd08df267f82070f16015d9953d3edc85002dcafd
|
7
|
+
data.tar.gz: 746475ff0522b512e28f7bfd83a7e54be7445a29abcd9b1c8aa16c7b6c39b6f97f5e553ac228b3bad98af8b5f828c4fb6c311f75ddd4b286045ba9a353f0fd8a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
## 1.6.1 / 2024-12-02
|
2
|
+
|
3
|
+
This is a performance and security release which addresses several possible XSS vulnerabilities.
|
4
|
+
|
5
|
+
* The dependency on Nokogiri is updated to v1.15.7 or >=1.16.8.
|
6
|
+
|
7
|
+
This change addresses CVE-2024-53985 (GHSA-w8gc-x259-rc7x).
|
8
|
+
|
9
|
+
*Mike Dalessio*
|
10
|
+
|
11
|
+
* Disallowed tags will be pruned when they appear in foreign content (i.e. SVG or MathML content),
|
12
|
+
regardless of the `prune:` option value. Previously, disallowed tags were "stripped" unless the
|
13
|
+
gem was configured with the `prune: true` option.
|
14
|
+
|
15
|
+
The CVEs addressed by this change are:
|
16
|
+
|
17
|
+
- CVE-2024-53986 (GHSA-638j-pmjw-jq48)
|
18
|
+
- CVE-2024-53987 (GHSA-2x5m-9ch4-qgrr)
|
19
|
+
|
20
|
+
*Mike Dalessio*
|
21
|
+
|
22
|
+
* The tags "noscript", "mglyph", and "malignmark" will not be allowed, even if explicitly added to
|
23
|
+
the allowlist. If applications try to allow any of these tags, a warning is emitted and the tags
|
24
|
+
are removed from the allow-list.
|
25
|
+
|
26
|
+
The CVEs addressed by this change are:
|
27
|
+
|
28
|
+
- CVE-2024-53988 (GHSA-cfjx-w229-hgx5)
|
29
|
+
- CVE-2024-53989 (GHSA-rxv5-gxqc-xx8g)
|
30
|
+
|
31
|
+
Please note that we _may_ restore support for allowing "noscript" in a future release. We do not
|
32
|
+
expect to ever allow "mglyph" or "malignmark", though, especially since browser support is minimal
|
33
|
+
for these tags.
|
34
|
+
|
35
|
+
*Mike Dalessio*
|
36
|
+
|
37
|
+
* Improve performance by eliminating needless operations on attributes that are being removed. #188
|
38
|
+
|
39
|
+
*Mike Dalessio*
|
40
|
+
|
41
|
+
|
1
42
|
## 1.6.0 / 2023-05-26
|
2
43
|
|
3
44
|
* Dependencies have been updated:
|
data/README.md
CHANGED
data/lib/rails/html/sanitizer.rb
CHANGED
data/lib/rails/html/scrubbers.rb
CHANGED
@@ -72,10 +72,11 @@ module Rails
|
|
72
72
|
return CONTINUE if skip_node?(node)
|
73
73
|
|
74
74
|
unless (node.element? || node.comment?) && keep_node?(node)
|
75
|
-
return STOP
|
75
|
+
return STOP unless scrub_node(node) == CONTINUE
|
76
76
|
end
|
77
77
|
|
78
78
|
scrub_attributes(node)
|
79
|
+
CONTINUE
|
79
80
|
end
|
80
81
|
|
81
82
|
protected
|
@@ -100,15 +101,22 @@ module Rails
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def scrub_node(node)
|
103
|
-
node
|
104
|
+
# If a node has a namespace, then it's a tag in either a `math` or `svg` foreign context,
|
105
|
+
# and we should always prune it to avoid namespace confusion and mutation XSS vectors.
|
106
|
+
unless prune || node.namespace
|
107
|
+
node.before(node.children)
|
108
|
+
end
|
104
109
|
node.remove
|
105
110
|
end
|
106
111
|
|
107
112
|
def scrub_attributes(node)
|
108
113
|
if @attributes
|
109
114
|
node.attribute_nodes.each do |attr|
|
110
|
-
|
111
|
-
|
115
|
+
if scrub_attribute?(attr.name)
|
116
|
+
attr.remove
|
117
|
+
else
|
118
|
+
scrub_attribute(node, attr)
|
119
|
+
end
|
112
120
|
end
|
113
121
|
|
114
122
|
scrub_css_attribute(node)
|
@@ -130,6 +138,24 @@ module Rails
|
|
130
138
|
if var && !var.is_a?(Enumerable)
|
131
139
|
raise ArgumentError, "You should pass :#{name} as an Enumerable"
|
132
140
|
end
|
141
|
+
|
142
|
+
if var && name == :tags
|
143
|
+
if var.include?("mglyph")
|
144
|
+
warn("WARNING: 'mglyph' tags cannot be allowed by the PermitScrubber and will be scrubbed")
|
145
|
+
var.delete("mglyph")
|
146
|
+
end
|
147
|
+
|
148
|
+
if var.include?("malignmark")
|
149
|
+
warn("WARNING: 'malignmark' tags cannot be allowed by the PermitScrubber and will be scrubbed")
|
150
|
+
var.delete("malignmark")
|
151
|
+
end
|
152
|
+
|
153
|
+
if var.include?("noscript")
|
154
|
+
warn("WARNING: 'noscript' tags cannot be allowed by the PermitScrubber and will be scrubbed")
|
155
|
+
var.delete("noscript")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
133
159
|
var
|
134
160
|
end
|
135
161
|
|
@@ -140,9 +166,7 @@ module Rails
|
|
140
166
|
attr_node.node_name
|
141
167
|
end
|
142
168
|
|
143
|
-
if Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name)
|
144
|
-
return if Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
|
145
|
-
end
|
169
|
+
return if Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name) && Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
|
146
170
|
|
147
171
|
if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
|
148
172
|
Loofah::HTML5::Scrub.scrub_attribute_that_allows_local_ref(attr_node)
|
data/test/sanitizer_test.rb
CHANGED
@@ -728,8 +728,6 @@ module SanitizerTests
|
|
728
728
|
end
|
729
729
|
|
730
730
|
def test_uri_escaping_of_href_attr_in_a_tag_in_safe_list_sanitizer
|
731
|
-
skip if RUBY_VERSION < "2.3"
|
732
|
-
|
733
731
|
html = %{<a href='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
|
734
732
|
|
735
733
|
text = safe_list_sanitize(html)
|
@@ -747,8 +745,6 @@ module SanitizerTests
|
|
747
745
|
end
|
748
746
|
|
749
747
|
def test_uri_escaping_of_src_attr_in_a_tag_in_safe_list_sanitizer
|
750
|
-
skip if RUBY_VERSION < "2.3"
|
751
|
-
|
752
748
|
html = %{<a src='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
|
753
749
|
|
754
750
|
text = safe_list_sanitize(html)
|
@@ -766,8 +762,6 @@ module SanitizerTests
|
|
766
762
|
end
|
767
763
|
|
768
764
|
def test_uri_escaping_of_name_attr_in_a_tag_in_safe_list_sanitizer
|
769
|
-
skip if RUBY_VERSION < "2.3"
|
770
|
-
|
771
765
|
html = %{<a name='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
|
772
766
|
|
773
767
|
text = safe_list_sanitize(html)
|
@@ -785,8 +779,6 @@ module SanitizerTests
|
|
785
779
|
end
|
786
780
|
|
787
781
|
def test_uri_escaping_of_name_action_in_a_tag_in_safe_list_sanitizer
|
788
|
-
skip if RUBY_VERSION < "2.3"
|
789
|
-
|
790
782
|
html = %{<a action='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
|
791
783
|
|
792
784
|
text = safe_list_sanitize(html, attributes: ["action"])
|
@@ -926,7 +918,7 @@ module SanitizerTests
|
|
926
918
|
# libxml2
|
927
919
|
"<svg><style><script>alert(1)</script></style></svg>",
|
928
920
|
# libgumbo
|
929
|
-
"<svg><style
|
921
|
+
"<svg><style></style></svg>",
|
930
922
|
]
|
931
923
|
|
932
924
|
assert_includes(acceptable_results, actual)
|
@@ -984,6 +976,76 @@ module SanitizerTests
|
|
984
976
|
assert_includes(acceptable_results, actual)
|
985
977
|
end
|
986
978
|
|
979
|
+
def test_combination_of_svg_and_style_with_escaped_img_payload
|
980
|
+
# https://hackerone.com/reports/2503220
|
981
|
+
input, tags = "<svg><style><img src onerror=alert(1)>", ["svg", "style"]
|
982
|
+
actual = safe_list_sanitize(input, tags: tags)
|
983
|
+
acceptable_results = [
|
984
|
+
# libxml2
|
985
|
+
"<svg><style>&lt;img src onerror=alert(1)></style></svg>",
|
986
|
+
# libgumbo
|
987
|
+
"<svg><style><img src onerror=alert(1)></style></svg>",
|
988
|
+
]
|
989
|
+
|
990
|
+
assert_includes(acceptable_results, actual)
|
991
|
+
end
|
992
|
+
|
993
|
+
def test_combination_of_math_and_style_with_escaped_img_payload
|
994
|
+
# https://hackerone.com/reports/2503220
|
995
|
+
input, tags = "<math><style><img src onerror=alert(1)>", ["math", "style"]
|
996
|
+
actual = safe_list_sanitize(input, tags: tags)
|
997
|
+
acceptable_results = [
|
998
|
+
# libxml2
|
999
|
+
"<math><style>&lt;img src onerror=alert(1)></style></math>",
|
1000
|
+
# libgumbo
|
1001
|
+
"<math><style><img src onerror=alert(1)></style></math>",
|
1002
|
+
]
|
1003
|
+
|
1004
|
+
assert_includes(acceptable_results, actual)
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
def test_combination_of_style_and_disallowed_svg_with_script_payload
|
1008
|
+
# https://hackerone.com/reports/2519936
|
1009
|
+
input, tags = "<svg><style><style class='</style><script>alert(1)</script>'>", ["style"]
|
1010
|
+
actual = safe_list_sanitize(input, tags: tags)
|
1011
|
+
acceptable_results = [
|
1012
|
+
# libxml2
|
1013
|
+
"<style><style class='</style>alert(1)'>",
|
1014
|
+
# libgumbo
|
1015
|
+
"",
|
1016
|
+
]
|
1017
|
+
|
1018
|
+
assert_includes(acceptable_results, actual)
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
def test_combination_of_style_and_disallowed_math_with_script_payload
|
1022
|
+
# https://hackerone.com/reports/2519936
|
1023
|
+
input, tags = "<math><style><style class='</style><script>alert(1)</script>'>", ["style"]
|
1024
|
+
actual = safe_list_sanitize(input, tags: tags)
|
1025
|
+
acceptable_results = [
|
1026
|
+
# libxml2
|
1027
|
+
"<style><style class='</style>alert(1)'>",
|
1028
|
+
# libgumbo
|
1029
|
+
"",
|
1030
|
+
]
|
1031
|
+
|
1032
|
+
assert_includes(acceptable_results, actual)
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def test_math_with_disallowed_mtext_and_img_payload
|
1036
|
+
# https://hackerone.com/reports/2519941
|
1037
|
+
input, tags = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>", ["math", "style"]
|
1038
|
+
actual = safe_list_sanitize(input, tags: tags)
|
1039
|
+
acceptable_results = [
|
1040
|
+
# libxml2
|
1041
|
+
"<math><style><img src=: onerror=alert(1)></style></math>",
|
1042
|
+
# libgumbo
|
1043
|
+
"<math></math>",
|
1044
|
+
]
|
1045
|
+
|
1046
|
+
assert_includes(acceptable_results, actual)
|
1047
|
+
end
|
1048
|
+
|
987
1049
|
def test_should_sanitize_illegal_style_properties
|
988
1050
|
raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
|
989
1051
|
expected = %(display:block;width:100%;height:100%;background-color:black;background-x:center;background-y:center;)
|
@@ -1034,6 +1096,64 @@ module SanitizerTests
|
|
1034
1096
|
assert_equal "", sanitize_css(raw)
|
1035
1097
|
end
|
1036
1098
|
|
1099
|
+
def test_should_prune_mglyph
|
1100
|
+
# https://hackerone.com/reports/2519936
|
1101
|
+
input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
|
1102
|
+
tags = %w(math mtext table mglyph style)
|
1103
|
+
|
1104
|
+
actual = nil
|
1105
|
+
assert_output(nil, /WARNING: 'mglyph' tags cannot be allowed by the PermitScrubber/) do
|
1106
|
+
actual = safe_list_sanitize(input, tags: tags)
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
acceptable_results = [
|
1110
|
+
# libxml2
|
1111
|
+
"<math><mtext><table><style><img src=: onerror=alert(1)></style></table></mtext></math>",
|
1112
|
+
# libgumbo
|
1113
|
+
"<math><mtext><style><img src=: onerror=alert(1)></style><table></table></mtext></math>",
|
1114
|
+
]
|
1115
|
+
|
1116
|
+
assert_includes(acceptable_results, actual)
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def test_should_prune_malignmark
|
1120
|
+
# https://hackerone.com/reports/2519936
|
1121
|
+
input = "<math><mtext><table><malignmark><style><img src=: onerror=alert(1)>"
|
1122
|
+
tags = %w(math mtext table malignmark style)
|
1123
|
+
|
1124
|
+
actual = nil
|
1125
|
+
assert_output(nil, /WARNING: 'malignmark' tags cannot be allowed by the PermitScrubber/) do
|
1126
|
+
actual = safe_list_sanitize(input, tags: tags)
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
acceptable_results = [
|
1130
|
+
# libxml2
|
1131
|
+
"<math><mtext><table><style><img src=: onerror=alert(1)></style></table></mtext></math>",
|
1132
|
+
# libgumbo
|
1133
|
+
"<math><mtext><style><img src=: onerror=alert(1)></style><table></table></mtext></math>",
|
1134
|
+
]
|
1135
|
+
|
1136
|
+
assert_includes(acceptable_results, actual)
|
1137
|
+
end
|
1138
|
+
|
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
|
+
|
1037
1157
|
protected
|
1038
1158
|
def safe_list_sanitize(input, options = {})
|
1039
1159
|
module_under_test::SafeListSanitizer.new.sanitize(input, options)
|
@@ -1083,5 +1203,84 @@ module SanitizerTests
|
|
1083
1203
|
class HTML5SafeListSanitizerTest < Minitest::Test
|
1084
1204
|
@module_under_test = Rails::HTML5
|
1085
1205
|
include SafeListSanitizerTest
|
1206
|
+
|
1207
|
+
def test_should_not_be_vulnerable_to_nokogiri_foreign_style_serialization_bug
|
1208
|
+
# https://hackerone.com/reports/2503220
|
1209
|
+
input = "<svg><style><img src onerror=alert(1)>"
|
1210
|
+
result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: ["svg", "style"])
|
1211
|
+
browser = Nokogiri::HTML5::Document.parse(result)
|
1212
|
+
xss = browser.at_xpath("//img/@onerror")
|
1213
|
+
|
1214
|
+
assert_nil(xss)
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
def test_should_not_be_vulnerable_to_ns_confusion_2519936
|
1218
|
+
# https://hackerone.com/reports/2519936
|
1219
|
+
input = "<math><style><style class='</style><script>alert(1)</script>'>"
|
1220
|
+
result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: ["style"])
|
1221
|
+
browser = Nokogiri::HTML5::Document.parse(result)
|
1222
|
+
xss = browser.at_xpath("//script")
|
1223
|
+
|
1224
|
+
assert_nil(xss)
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
def test_should_not_be_vulnerable_to_ns_confusion_2519941
|
1228
|
+
# https://hackerone.com/reports/2519941
|
1229
|
+
input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
|
1230
|
+
result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: %w(math style))
|
1231
|
+
browser = Nokogiri::HTML5::Document.parse(result)
|
1232
|
+
xss = browser.at_xpath("//img/@onerror")
|
1233
|
+
|
1234
|
+
assert_nil(xss)
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
def test_should_not_be_vulnerable_to_mglyph_namespace_confusion
|
1238
|
+
# https://hackerone.com/reports/2519936
|
1239
|
+
input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
|
1240
|
+
tags = %w(math mtext table mglyph style)
|
1241
|
+
|
1242
|
+
result = nil
|
1243
|
+
assert_output(nil, /WARNING/) do
|
1244
|
+
result = safe_list_sanitize(input, tags: tags)
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
browser = Nokogiri::HTML5::Document.parse(result)
|
1248
|
+
xss = browser.at_xpath("//img/@onerror")
|
1249
|
+
|
1250
|
+
assert_nil(xss)
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
def test_should_not_be_vulnerable_to_malignmark_namespace_confusion
|
1254
|
+
# https://hackerone.com/reports/2519936
|
1255
|
+
input = "<math><mtext><table><malignmark><style><img src=: onerror=alert(1)>"
|
1256
|
+
tags = %w(math mtext table malignmark style)
|
1257
|
+
|
1258
|
+
result = nil
|
1259
|
+
assert_output(nil, /WARNING/) do
|
1260
|
+
result = safe_list_sanitize(input, tags: tags)
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
browser = Nokogiri::HTML5::Document.parse(result)
|
1264
|
+
xss = browser.at_xpath("//img/@onerror")
|
1265
|
+
|
1266
|
+
assert_nil(xss)
|
1267
|
+
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
|
1086
1285
|
end if loofah_html5_support?
|
1087
1286
|
end
|
data/test/scrubbers_test.rb
CHANGED
@@ -121,6 +121,30 @@ class PermitScrubberTest < ScrubberTest
|
|
121
121
|
assert_scrubbed html, '<tag></tag><tag cooler=""></tag>'
|
122
122
|
end
|
123
123
|
|
124
|
+
def test_does_not_allow_safelisted_mglyph
|
125
|
+
# https://hackerone.com/reports/2519936
|
126
|
+
assert_output(nil, /WARNING: 'mglyph' tags cannot be allowed by the PermitScrubber/) do
|
127
|
+
@scrubber.tags = ["div", "mglyph", "span"]
|
128
|
+
end
|
129
|
+
assert_equal(["div", "span"], @scrubber.tags)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_does_not_allow_safelisted_malignmark
|
133
|
+
# https://hackerone.com/reports/2519936
|
134
|
+
assert_output(nil, /WARNING: 'malignmark' tags cannot be allowed by the PermitScrubber/) do
|
135
|
+
@scrubber.tags = ["div", "malignmark", "span"]
|
136
|
+
end
|
137
|
+
assert_equal(["div", "span"], @scrubber.tags)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_does_not_allow_safelisted_noscript
|
141
|
+
# https://hackerone.com/reports/2509647
|
142
|
+
assert_output(nil, /WARNING: 'noscript' tags cannot be allowed by the PermitScrubber/) do
|
143
|
+
@scrubber.tags = ["div", "noscript", "span"]
|
144
|
+
end
|
145
|
+
assert_equal(["div", "span"], @scrubber.tags)
|
146
|
+
end
|
147
|
+
|
124
148
|
def test_leaves_text
|
125
149
|
assert_scrubbed("some text")
|
126
150
|
end
|
@@ -207,11 +231,65 @@ class ReturningStopFromScrubNodeTest < ScrubberTest
|
|
207
231
|
end
|
208
232
|
end
|
209
233
|
|
210
|
-
|
211
|
-
|
234
|
+
class ScrubContinuer < Rails::HTML::PermitScrubber
|
235
|
+
def scrub_node(node)
|
236
|
+
Loofah::Scrubber::CONTINUE
|
237
|
+
end
|
212
238
|
end
|
213
239
|
|
214
240
|
def test_returns_stop_from_scrub_if_scrub_node_does
|
241
|
+
@scrubber = ScrubStopper.new
|
215
242
|
assert_scrub_stopped "<script>remove me</script>"
|
216
243
|
end
|
244
|
+
|
245
|
+
def test_returns_continue_from_scrub_if_scrub_node_does
|
246
|
+
@scrubber = ScrubContinuer.new
|
247
|
+
assert_node_skipped "<script>keep me</script>"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
class PermitScrubberMinimalOperationsTest < ScrubberTest
|
252
|
+
class TestPermitScrubber < Rails::HTML::PermitScrubber
|
253
|
+
def initialize
|
254
|
+
@scrub_attribute_args = []
|
255
|
+
@scrub_attributes_args = []
|
256
|
+
|
257
|
+
super
|
258
|
+
|
259
|
+
self.tags = ["div"]
|
260
|
+
self.attributes = ["class"]
|
261
|
+
end
|
262
|
+
|
263
|
+
def scrub_attributes(node)
|
264
|
+
@scrub_attributes_args << node.name
|
265
|
+
|
266
|
+
super
|
267
|
+
end
|
268
|
+
|
269
|
+
def scrub_attribute(node, attr)
|
270
|
+
@scrub_attribute_args << [node.name, attr.name]
|
271
|
+
|
272
|
+
super
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_does_not_scrub_removed_attributes
|
277
|
+
@scrubber = TestPermitScrubber.new
|
278
|
+
|
279
|
+
input = "<div class='foo' href='bar'></div>"
|
280
|
+
frag = scrub_fragment(input)
|
281
|
+
assert_equal("<div class=\"foo\"></div>", frag)
|
282
|
+
|
283
|
+
assert_equal([["div", "class"]], @scrubber.instance_variable_get(:@scrub_attribute_args))
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_does_not_scrub_attributes_of_a_removed_node
|
287
|
+
@scrubber = TestPermitScrubber.new
|
288
|
+
|
289
|
+
input = "<div class='foo' href='bar'><svg xlink:href='asdf'><set></set></svg></div>"
|
290
|
+
frag = scrub_fragment(input)
|
291
|
+
assert_equal("<div class=\"foo\"></div>", frag)
|
292
|
+
|
293
|
+
assert_equal(["div"], @scrubber.instance_variable_get(:@scrub_attributes_args))
|
294
|
+
end
|
217
295
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-html-sanitizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Mendonça França
|
8
8
|
- Kasper Timm Hansen
|
9
9
|
- Mike Dalessio
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-12-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: loofah
|
@@ -30,16 +30,70 @@ dependencies:
|
|
30
30
|
name: nokogiri
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- - "
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 1.15.7
|
36
|
+
- - "!="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 1.16.0
|
39
|
+
- - "!="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.16.0.rc1
|
42
|
+
- - "!="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.16.1
|
45
|
+
- - "!="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.16.2
|
48
|
+
- - "!="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.16.3
|
51
|
+
- - "!="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.16.4
|
54
|
+
- - "!="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.16.5
|
57
|
+
- - "!="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.16.6
|
60
|
+
- - "!="
|
34
61
|
- !ruby/object:Gem::Version
|
35
|
-
version:
|
62
|
+
version: 1.16.7
|
36
63
|
type: :runtime
|
37
64
|
prerelease: false
|
38
65
|
version_requirements: !ruby/object:Gem::Requirement
|
39
66
|
requirements:
|
40
|
-
- - "
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.15.7
|
70
|
+
- - "!="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.16.0
|
73
|
+
- - "!="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.16.0.rc1
|
76
|
+
- - "!="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.16.1
|
79
|
+
- - "!="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.16.2
|
82
|
+
- - "!="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.16.3
|
85
|
+
- - "!="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.16.4
|
88
|
+
- - "!="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.16.5
|
91
|
+
- - "!="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.16.6
|
94
|
+
- - "!="
|
41
95
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
96
|
+
version: 1.16.7
|
43
97
|
description: HTML sanitization for Rails applications
|
44
98
|
email:
|
45
99
|
- rafaelmfranca@gmail.com
|
@@ -64,10 +118,10 @@ licenses:
|
|
64
118
|
- MIT
|
65
119
|
metadata:
|
66
120
|
bug_tracker_uri: https://github.com/rails/rails-html-sanitizer/issues
|
67
|
-
changelog_uri: https://github.com/rails/rails-html-sanitizer/blob/v1.6.
|
68
|
-
documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.6.
|
69
|
-
source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.6.
|
70
|
-
post_install_message:
|
121
|
+
changelog_uri: https://github.com/rails/rails-html-sanitizer/blob/v1.6.1/CHANGELOG.md
|
122
|
+
documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.6.1
|
123
|
+
source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.6.1
|
124
|
+
post_install_message:
|
71
125
|
rdoc_options: []
|
72
126
|
require_paths:
|
73
127
|
- lib
|
@@ -82,8 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
136
|
- !ruby/object:Gem::Version
|
83
137
|
version: '0'
|
84
138
|
requirements: []
|
85
|
-
rubygems_version: 3.
|
86
|
-
signing_key:
|
139
|
+
rubygems_version: 3.5.22
|
140
|
+
signing_key:
|
87
141
|
specification_version: 4
|
88
142
|
summary: This gem is responsible to sanitize HTML fragments in Rails applications.
|
89
143
|
test_files:
|