rails-html-sanitizer 1.5.0 → 1.6.2

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.
@@ -1,11 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "minitest/autorun"
2
4
  require "rails-html-sanitizer"
3
5
 
4
6
  class ScrubberTest < Minitest::Test
5
7
  protected
8
+ def scrub_fragment(html)
9
+ Loofah.scrub_fragment(html, @scrubber).to_s
10
+ end
6
11
 
7
12
  def assert_scrubbed(html, expected = html)
8
- output = Loofah.scrub_fragment(html, @scrubber).to_s
13
+ output = scrub_fragment(html)
9
14
  assert_equal expected, output
10
15
  end
11
16
 
@@ -28,9 +33,8 @@ class ScrubberTest < Minitest::Test
28
33
  end
29
34
 
30
35
  class PermitScrubberTest < ScrubberTest
31
-
32
36
  def setup
33
- @scrubber = Rails::Html::PermitScrubber.new
37
+ @scrubber = Rails::HTML::PermitScrubber.new
34
38
  end
35
39
 
36
40
  def test_responds_to_scrub
@@ -38,51 +42,60 @@ class PermitScrubberTest < ScrubberTest
38
42
  end
39
43
 
40
44
  def test_default_scrub_behavior
41
- assert_scrubbed '<tag>hello</tag>', 'hello'
45
+ assert_scrubbed "<tag>hello</tag>", "hello"
42
46
  end
43
47
 
44
48
  def test_default_scrub_removes_comments
45
- assert_scrubbed('<div>one</div><!-- two --><span>three</span>',
46
- '<div>one</div><span>three</span>')
49
+ assert_scrubbed("<div>one</div><!-- two --><span>three</span>",
50
+ "<div>one</div><span>three</span>")
47
51
  end
48
52
 
49
53
  def test_default_scrub_removes_processing_instructions
50
- assert_scrubbed('<div>one</div><?div two><span>three</span>',
51
- '<div>one</div><span>three</span>')
54
+ input = "<div>one</div><?div two><span>three</span>"
55
+ result = scrub_fragment(input)
56
+
57
+ acceptable_results = [
58
+ # jruby cyberneko (nokogiri < 1.14.0)
59
+ "<div>one</div>",
60
+ # everything else
61
+ "<div>one</div><span>three</span>",
62
+ ]
63
+
64
+ assert_includes(acceptable_results, result)
52
65
  end
53
66
 
54
67
  def test_default_attributes_removal_behavior
55
- assert_scrubbed '<p cooler="hello">hello</p>', '<p>hello</p>'
68
+ assert_scrubbed '<p cooler="hello">hello</p>', "<p>hello</p>"
56
69
  end
57
70
 
58
71
  def test_leaves_supplied_tags
59
72
  @scrubber.tags = %w(a)
60
- assert_scrubbed '<a>hello</a>'
73
+ assert_scrubbed "<a>hello</a>"
61
74
  end
62
75
 
63
76
  def test_leaves_only_supplied_tags
64
- html = '<tag>leave me <span>now</span></tag>'
77
+ html = "<tag>leave me <span>now</span></tag>"
65
78
  @scrubber.tags = %w(tag)
66
- assert_scrubbed html, '<tag>leave me now</tag>'
79
+ assert_scrubbed html, "<tag>leave me now</tag>"
67
80
  end
68
81
 
69
82
  def test_prunes_tags
70
- @scrubber = Rails::Html::PermitScrubber.new(prune: true)
83
+ @scrubber = Rails::HTML::PermitScrubber.new(prune: true)
71
84
  @scrubber.tags = %w(tag)
72
- html = '<tag>leave me <span>now</span></tag>'
73
- assert_scrubbed html, '<tag>leave me </tag>'
85
+ html = "<tag>leave me <span>now</span></tag>"
86
+ assert_scrubbed html, "<tag>leave me </tag>"
74
87
  end
75
88
 
76
89
  def test_leaves_comments_when_supplied_as_tag
77
90
  @scrubber.tags = %w(div comment)
78
- assert_scrubbed('<div>one</div><!-- two --><span>three</span>',
79
- '<div>one</div><!-- two -->three')
91
+ assert_scrubbed("<div>one</div><!-- two --><span>three</span>",
92
+ "<div>one</div><!-- two -->three")
80
93
  end
81
94
 
82
95
  def test_leaves_only_supplied_tags_nested
83
- html = '<tag>leave <em>me <span>now</span></em></tag>'
96
+ html = "<tag>leave <em>me <span>now</span></em></tag>"
84
97
  @scrubber.tags = %w(tag)
85
- assert_scrubbed html, '<tag>leave me now</tag>'
98
+ assert_scrubbed html, "<tag>leave me now</tag>"
86
99
  end
87
100
 
88
101
  def test_leaves_supplied_attributes
@@ -108,17 +121,41 @@ class PermitScrubberTest < ScrubberTest
108
121
  assert_scrubbed html, '<tag></tag><tag cooler=""></tag>'
109
122
  end
110
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
+
111
148
  def test_leaves_text
112
- assert_scrubbed('some text')
149
+ assert_scrubbed("some text")
113
150
  end
114
151
 
115
152
  def test_skips_text_nodes
116
- assert_node_skipped('some text')
153
+ assert_node_skipped("some text")
117
154
  end
118
155
 
119
156
  def test_tags_accessor_validation
120
157
  e = assert_raises(ArgumentError) do
121
- @scrubber.tags = 'tag'
158
+ @scrubber.tags = "tag"
122
159
  end
123
160
 
124
161
  assert_equal "You should pass :tags as an Enumerable", e.message
@@ -127,7 +164,7 @@ class PermitScrubberTest < ScrubberTest
127
164
 
128
165
  def test_attributes_accessor_validation
129
166
  e = assert_raises(ArgumentError) do
130
- @scrubber.attributes = 'cooler'
167
+ @scrubber.attributes = "cooler"
131
168
  end
132
169
 
133
170
  assert_equal "You should pass :attributes as an Enumerable", e.message
@@ -137,19 +174,19 @@ end
137
174
 
138
175
  class TargetScrubberTest < ScrubberTest
139
176
  def setup
140
- @scrubber = Rails::Html::TargetScrubber.new
177
+ @scrubber = Rails::HTML::TargetScrubber.new
141
178
  end
142
179
 
143
180
  def test_targeting_tags_removes_only_them
144
181
  @scrubber.tags = %w(a h1)
145
- html = '<script></script><a></a><h1></h1>'
146
- assert_scrubbed html, '<script></script>'
182
+ html = "<script></script><a></a><h1></h1>"
183
+ assert_scrubbed html, "<script></script>"
147
184
  end
148
185
 
149
186
  def test_targeting_tags_removes_only_them_nested
150
187
  @scrubber.tags = %w(a)
151
- html = '<tag><a><tag><a></a></tag></a></tag>'
152
- assert_scrubbed html, '<tag><tag></tag></tag>'
188
+ html = "<tag><a><tag><a></a></tag></a></tag>"
189
+ assert_scrubbed html, "<tag><tag></tag></tag>"
153
190
  end
154
191
 
155
192
  def test_targeting_attributes_removes_only_them
@@ -166,39 +203,93 @@ class TargetScrubberTest < ScrubberTest
166
203
  end
167
204
 
168
205
  def test_prunes_tags
169
- @scrubber = Rails::Html::TargetScrubber.new(prune: true)
206
+ @scrubber = Rails::HTML::TargetScrubber.new(prune: true)
170
207
  @scrubber.tags = %w(span)
171
- html = '<tag>leave me <span>now</span></tag>'
172
- assert_scrubbed html, '<tag>leave me </tag>'
208
+ html = "<tag>leave me <span>now</span></tag>"
209
+ assert_scrubbed html, "<tag>leave me </tag>"
173
210
  end
174
211
  end
175
212
 
176
213
  class TextOnlyScrubberTest < ScrubberTest
177
214
  def setup
178
- @scrubber = Rails::Html::TextOnlyScrubber.new
215
+ @scrubber = Rails::HTML::TextOnlyScrubber.new
179
216
  end
180
217
 
181
218
  def test_removes_all_tags_and_keep_the_content
182
- assert_scrubbed '<tag>hello</tag>', 'hello'
219
+ assert_scrubbed "<tag>hello</tag>", "hello"
183
220
  end
184
221
 
185
222
  def test_skips_text_nodes
186
- assert_node_skipped('some text')
223
+ assert_node_skipped("some text")
187
224
  end
188
225
  end
189
226
 
190
227
  class ReturningStopFromScrubNodeTest < ScrubberTest
191
- class ScrubStopper < Rails::Html::PermitScrubber
228
+ class ScrubStopper < Rails::HTML::PermitScrubber
192
229
  def scrub_node(node)
193
230
  Loofah::Scrubber::STOP
194
231
  end
195
232
  end
196
233
 
197
- def setup
198
- @scrubber = ScrubStopper.new
234
+ class ScrubContinuer < Rails::HTML::PermitScrubber
235
+ def scrub_node(node)
236
+ Loofah::Scrubber::CONTINUE
237
+ end
199
238
  end
200
239
 
201
240
  def test_returns_stop_from_scrub_if_scrub_node_does
202
- assert_scrub_stopped '<script>remove me</script>'
241
+ @scrubber = ScrubStopper.new
242
+ assert_scrub_stopped "<script>remove me</script>"
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))
203
294
  end
204
295
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-html-sanitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Mendonça França
8
8
  - Kasper Timm Hansen
9
- autorequire:
9
+ - Mike Dalessio
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2023-01-20 00:00:00.000000000 Z
13
+ date: 2024-12-12 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: loofah
@@ -17,80 +18,87 @@ dependencies:
17
18
  requirements:
18
19
  - - "~>"
19
20
  - !ruby/object:Gem::Version
20
- version: '2.19'
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 2.19.1
21
+ version: '2.21'
24
22
  type: :runtime
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
25
  requirements:
28
26
  - - "~>"
29
27
  - !ruby/object:Gem::Version
30
- version: '2.19'
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 2.19.1
28
+ version: '2.21'
34
29
  - !ruby/object:Gem::Dependency
35
- name: bundler
30
+ name: nokogiri
36
31
  requirement: !ruby/object:Gem::Requirement
37
32
  requirements:
38
33
  - - ">="
39
34
  - !ruby/object:Gem::Version
40
- version: '1.3'
41
- type: :development
42
- prerelease: false
43
- version_requirements: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
35
+ version: 1.15.7
36
+ - - "!="
46
37
  - !ruby/object:Gem::Version
47
- version: '1.3'
48
- - !ruby/object:Gem::Dependency
49
- name: rake
50
- requirement: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
38
+ version: 1.16.0
39
+ - - "!="
53
40
  - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
41
+ version: 1.16.0.rc1
42
+ - - "!="
60
43
  - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
63
- name: minitest
64
- requirement: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
44
+ version: 1.16.1
45
+ - - "!="
67
46
  - !ruby/object:Gem::Version
68
- version: '0'
69
- type: :development
70
- prerelease: false
71
- version_requirements: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
47
+ version: 1.16.2
48
+ - - "!="
74
49
  - !ruby/object:Gem::Version
75
- version: '0'
76
- - !ruby/object:Gem::Dependency
77
- name: rails-dom-testing
78
- requirement: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
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
+ - - "!="
81
58
  - !ruby/object:Gem::Version
82
- version: '0'
83
- type: :development
59
+ version: 1.16.6
60
+ - - "!="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.16.7
63
+ type: :runtime
84
64
  prerelease: false
85
65
  version_requirements: !ruby/object:Gem::Requirement
86
66
  requirements:
87
67
  - - ">="
88
68
  - !ruby/object:Gem::Version
89
- version: '0'
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
+ - - "!="
95
+ - !ruby/object:Gem::Version
96
+ version: 1.16.7
90
97
  description: HTML sanitization for Rails applications
91
98
  email:
92
99
  - rafaelmfranca@gmail.com
93
100
  - kaspth@gmail.com
101
+ - mike.dalessio@gmail.com
94
102
  executables: []
95
103
  extensions: []
96
104
  extra_rdoc_files: []
@@ -102,6 +110,7 @@ files:
102
110
  - lib/rails/html/sanitizer.rb
103
111
  - lib/rails/html/sanitizer/version.rb
104
112
  - lib/rails/html/scrubbers.rb
113
+ - test/rails_api_test.rb
105
114
  - test/sanitizer_test.rb
106
115
  - test/scrubbers_test.rb
107
116
  homepage: https://github.com/rails/rails-html-sanitizer
@@ -109,10 +118,10 @@ licenses:
109
118
  - MIT
110
119
  metadata:
111
120
  bug_tracker_uri: https://github.com/rails/rails-html-sanitizer/issues
112
- changelog_uri: https://github.com/rails/rails-html-sanitizer/blob/v1.5.0/CHANGELOG.md
113
- documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.5.0
114
- source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.5.0
115
- post_install_message:
121
+ changelog_uri: https://github.com/rails/rails-html-sanitizer/blob/v1.6.2/CHANGELOG.md
122
+ documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.6.2
123
+ source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.6.2
124
+ post_install_message:
116
125
  rdoc_options: []
117
126
  require_paths:
118
127
  - lib
@@ -120,17 +129,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
129
  requirements:
121
130
  - - ">="
122
131
  - !ruby/object:Gem::Version
123
- version: '0'
132
+ version: 2.7.0
124
133
  required_rubygems_version: !ruby/object:Gem::Requirement
125
134
  requirements:
126
135
  - - ">="
127
136
  - !ruby/object:Gem::Version
128
137
  version: '0'
129
138
  requirements: []
130
- rubygems_version: 3.4.2
131
- signing_key:
139
+ rubygems_version: 3.3.22
140
+ signing_key:
132
141
  specification_version: 4
133
142
  summary: This gem is responsible to sanitize HTML fragments in Rails applications.
134
143
  test_files:
144
+ - test/rails_api_test.rb
135
145
  - test/sanitizer_test.rb
136
146
  - test/scrubbers_test.rb