loofah 2.1.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of loofah might be problematic. Click here for more details.

data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- require 'rubygems'
2
- gem 'hoe', '>= 2.3.0'
3
- require 'hoe'
4
- require 'concourse'
1
+ require "rubygems"
2
+ require "hoe"
3
+ require "concourse"
5
4
 
6
5
  Hoe.plugin :git
7
6
  Hoe.plugin :gemspec
@@ -12,23 +11,23 @@ Hoe.spec "loofah" do
12
11
  developer "Mike Dalessio", "mike.dalessio@gmail.com"
13
12
  developer "Bryan Helmkamp", "bryan@brynary.com"
14
13
 
15
- self.extra_rdoc_files = FileList["*.rdoc"]
16
- self.history_file = "CHANGELOG.md"
17
- self.readme_file = "README.rdoc"
18
- self.license "MIT"
14
+ self.extra_rdoc_files = FileList["*.md"]
15
+ self.history_file = "CHANGELOG.md"
16
+ self.readme_file = "README.md"
17
+ self.license "MIT"
19
18
 
20
- extra_deps << ["nokogiri", ">=1.5.9"]
21
- extra_deps << ["crass", "~> 1.0.2"]
19
+ extra_deps << ["nokogiri", ">=1.5.9"]
20
+ extra_deps << ["crass", "~> 1.0.2"]
22
21
 
23
- extra_dev_deps << ["rake", ">=0.8"]
22
+ extra_dev_deps << ["rake", "~> 12.3"]
24
23
  extra_dev_deps << ["minitest", "~>2.2"]
25
24
  extra_dev_deps << ["rr", "~>1.2.0"]
26
- extra_dev_deps << ["json", ">=0"]
27
- extra_dev_deps << ["hoe-gemspec", ">=0"]
28
- extra_dev_deps << ["hoe-debugging", ">=0"]
29
- extra_dev_deps << ["hoe-bundler", ">=0"]
30
- extra_dev_deps << ["hoe-git", ">=0"]
31
- extra_dev_deps << ["concourse", ">=0.14.0"]
25
+ extra_dev_deps << ["json", "~> 2.2.0"]
26
+ extra_dev_deps << ["hoe-gemspec", "~> 1.0"]
27
+ extra_dev_deps << ["hoe-debugging", "~> 2.0"]
28
+ extra_dev_deps << ["hoe-bundler", "~> 1.5"]
29
+ extra_dev_deps << ["hoe-git", "~> 1.6"]
30
+ extra_dev_deps << ["concourse", ">=0.26.0"]
32
31
  end
33
32
 
34
33
  task :gemspec do
@@ -71,9 +70,12 @@ task :doc_upload_to_rubyforge => :docs do
71
70
  end
72
71
  end
73
72
 
74
- desc "generate whitelists from W3C specifications"
75
- task :generate_whitelists do
76
- load "tasks/generate-whitelists"
73
+ desc "generate safelists from W3C specifications"
74
+ task :generate_safelists do
75
+ load "tasks/generate-safelists"
77
76
  end
78
77
 
79
- Concourse.new("loofah").create_tasks!
78
+ Concourse.new("loofah", fly_target: "ci") do |c|
79
+ c.add_pipeline "loofah", "loofah.yml"
80
+ c.add_pipeline "loofah-pr", "loofah-pr.yml"
81
+ end
@@ -0,0 +1,18 @@
1
+ # Security and Vulnerability Reporting
2
+
3
+ The Loofah core contributors take security very seriously and investigate all reported vulnerabilities.
4
+
5
+ If you would like to report a vulnerablity or have a security concern regarding Loofah, please [report it via HackerOne](https://hackerone.com/loofah/reports/new).
6
+
7
+ Your report will be acknowledged within 24 hours, and you'll receive a more detailed response within 72 hours indicating next steps in handling your report.
8
+
9
+ If you have not received a reply to your submission within 48 hours, there are a few steps you can take:
10
+
11
+ * Contact the current security coordinator (Mike Dalessio <mike.dalessio@gmail.com>)
12
+ * Email the Loofah user group at loofah-talk@googlegroups.com (archive at https://groups.google.com/forum/#!forum/loofah-talk)
13
+
14
+ Please note, the user group list is a public area. When escalating in that venue, please do not discuss your issue. Simply say that you're trying to get a hold of someone from the core team.
15
+
16
+ The information you share with the Loofah core contributors as part of this process will be kept confidential within the team, unless or until we need to share information upstream with our dependent libraries' core teams, at which point we will notify you.
17
+
18
+ If a vulnerability is first reported by you, we will credit you with the discovery in the public disclosure.
@@ -1,21 +1,22 @@
1
1
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
2
2
 
3
- require 'nokogiri'
3
+ require "nokogiri"
4
4
 
5
- require 'loofah/metahelpers'
6
- require 'loofah/elements'
5
+ require "loofah/metahelpers"
6
+ require "loofah/elements"
7
7
 
8
- require 'loofah/html5/whitelist'
9
- require 'loofah/html5/scrub'
8
+ require "loofah/html5/safelist"
9
+ require "loofah/html5/libxml2_workarounds"
10
+ require "loofah/html5/scrub"
10
11
 
11
- require 'loofah/scrubber'
12
- require 'loofah/scrubbers'
12
+ require "loofah/scrubber"
13
+ require "loofah/scrubbers"
13
14
 
14
- require 'loofah/instance_methods'
15
- require 'loofah/xml/document'
16
- require 'loofah/xml/document_fragment'
17
- require 'loofah/html/document'
18
- require 'loofah/html/document_fragment'
15
+ require "loofah/instance_methods"
16
+ require "loofah/xml/document"
17
+ require "loofah/xml/document_fragment"
18
+ require "loofah/html/document"
19
+ require "loofah/html/document_fragment"
19
20
 
20
21
  # == Strings and IO Objects as Input
21
22
  #
@@ -27,7 +28,7 @@ require 'loofah/html/document_fragment'
27
28
  #
28
29
  module Loofah
29
30
  # The version of Loofah you are using
30
- VERSION = '2.1.1'
31
+ VERSION = "2.3.0"
31
32
 
32
33
  class << self
33
34
  # Shortcut for Loofah::HTML::Document.parse
@@ -76,7 +77,7 @@ module Loofah
76
77
 
77
78
  # A helper to remove extraneous whitespace from text-ified HTML
78
79
  def remove_extraneous_whitespace(string)
79
- string.gsub(/\n\s*\n\s*\n/,"\n\n")
80
+ string.gsub(/\n\s*\n\s*\n/, "\n\n")
80
81
  end
81
82
  end
82
83
  end
@@ -2,13 +2,88 @@ require 'set'
2
2
 
3
3
  module Loofah
4
4
  module Elements
5
- # Block elements in HTML4
6
- STRICT_BLOCK_LEVEL = Set.new %w[address blockquote center dir div dl
7
- fieldset form h1 h2 h3 h4 h5 h6 hr isindex menu noframes
8
- noscript ol p pre table ul]
5
+ STRICT_BLOCK_LEVEL_HTML4 = Set.new %w[
6
+ address
7
+ blockquote
8
+ center
9
+ dir
10
+ div
11
+ dl
12
+ fieldset
13
+ form
14
+ h1
15
+ h2
16
+ h3
17
+ h4
18
+ h5
19
+ h6
20
+ hr
21
+ isindex
22
+ menu
23
+ noframes
24
+ noscript
25
+ ol
26
+ p
27
+ pre
28
+ table
29
+ ul
30
+ ]
9
31
 
10
- # The following elements may also be considered block-level elements since they may contain block-level elements
11
- LOOSE_BLOCK_LEVEL = Set.new %w[dd dt frameset li tbody td tfoot th thead tr]
32
+ # https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
33
+ STRICT_BLOCK_LEVEL_HTML5 = Set.new %w[
34
+ address
35
+ article
36
+ aside
37
+ blockquote
38
+ canvas
39
+ dd
40
+ div
41
+ dl
42
+ dt
43
+ fieldset
44
+ figcaption
45
+ figure
46
+ footer
47
+ form
48
+ h1
49
+ h2
50
+ h3
51
+ h4
52
+ h5
53
+ h6
54
+ header
55
+ hgroup
56
+ hr
57
+ li
58
+ main
59
+ nav
60
+ noscript
61
+ ol
62
+ output
63
+ p
64
+ pre
65
+ section
66
+ table
67
+ tfoot
68
+ ul
69
+ video
70
+ ]
71
+
72
+ STRICT_BLOCK_LEVEL = STRICT_BLOCK_LEVEL_HTML4 + STRICT_BLOCK_LEVEL_HTML5
73
+
74
+ # The following elements may also be considered block-level
75
+ # elements since they may contain block-level elements
76
+ LOOSE_BLOCK_LEVEL = Set.new %w[dd
77
+ dt
78
+ frameset
79
+ li
80
+ tbody
81
+ td
82
+ tfoot
83
+ th
84
+ thead
85
+ tr
86
+ ]
12
87
 
13
88
  BLOCK_LEVEL = STRICT_BLOCK_LEVEL + LOOSE_BLOCK_LEVEL
14
89
  end
@@ -46,8 +46,13 @@ module Loofah
46
46
  @full_sanitizer ||= ::Loofah::Helpers::ActionView::FullSanitizer.new
47
47
  end
48
48
 
49
+ def safe_list_sanitizer
50
+ @safe_list_sanitizer ||= ::Loofah::Helpers::ActionView::SafeListSanitizer.new
51
+ end
52
+
49
53
  def white_list_sanitizer
50
- @white_list_sanitizer ||= ::Loofah::Helpers::ActionView::WhiteListSanitizer.new
54
+ warn "warning: white_list_sanitizer is deprecated, please use safe_list_sanitizer instead."
55
+ safe_list_sanitizer
51
56
  end
52
57
  end
53
58
 
@@ -73,13 +78,13 @@ module Loofah
73
78
  #
74
79
  # To use by default, call this in an application initializer:
75
80
  #
76
- # ActionView::Helpers::SanitizeHelper.white_list_sanitizer = ::Loofah::Helpers::ActionView::WhiteListSanitizer.new
81
+ # ActionView::Helpers::SanitizeHelper.safe_list_sanitizer = ::Loofah::Helpers::ActionView::SafeListSanitizer.new
77
82
  #
78
83
  # Or, to generally opt-in to Loofah's view sanitizers:
79
84
  #
80
85
  # Loofah::Helpers::ActionView.set_as_default_sanitizer
81
86
  #
82
- class WhiteListSanitizer
87
+ class SafeListSanitizer
83
88
  def sanitize html, *args
84
89
  Loofah::Helpers.sanitize html
85
90
  end
@@ -88,6 +93,11 @@ module Loofah
88
93
  Loofah::Helpers.sanitize_css style_string
89
94
  end
90
95
  end
96
+
97
+ WhiteListSanitizer = SafeListSanitizer
98
+ if Object.respond_to?(:deprecate_constant)
99
+ deprecate_constant :WhiteListSanitizer
100
+ end
91
101
  end
92
102
  end
93
103
  end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ require 'set'
3
+
4
+ module Loofah
5
+ #
6
+ # constants related to working around unhelpful libxml2 behavior
7
+ #
8
+ # ಠ_ಠ
9
+ #
10
+ module LibxmlWorkarounds
11
+ #
12
+ # these attributes and qualifying parent tags are determined by the code at:
13
+ #
14
+ # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714
15
+ #
16
+ # see comments about CVE-2018-8048 within the tests for more information
17
+ #
18
+ BROKEN_ESCAPING_ATTRIBUTES = Set.new %w[
19
+ href
20
+ action
21
+ src
22
+ name
23
+ ]
24
+ BROKEN_ESCAPING_ATTRIBUTES_QUALIFYING_TAG = {"name" => "a"}
25
+ end
26
+ end
@@ -0,0 +1,800 @@
1
+ require 'set'
2
+
3
+ module Loofah
4
+ module HTML5 # :nodoc:
5
+ #
6
+ # HTML safelist lifted from HTML5lib sanitizer code:
7
+ #
8
+ # http://code.google.com/p/html5lib/
9
+ #
10
+ # <html5_license>
11
+ #
12
+ # Copyright (c) 2006-2008 The Authors
13
+ #
14
+ # Contributors:
15
+ # James Graham - jg307@cam.ac.uk
16
+ # Anne van Kesteren - annevankesteren@gmail.com
17
+ # Lachlan Hunt - lachlan.hunt@lachy.id.au
18
+ # Matt McDonald - kanashii@kanashii.ca
19
+ # Sam Ruby - rubys@intertwingly.net
20
+ # Ian Hickson (Google) - ian@hixie.ch
21
+ # Thomas Broyer - t.broyer@ltgt.net
22
+ # Jacques Distler - distler@golem.ph.utexas.edu
23
+ # Henri Sivonen - hsivonen@iki.fi
24
+ # The Mozilla Foundation (contributions from Henri Sivonen since 2008)
25
+ #
26
+ # Permission is hereby granted, free of charge, to any person
27
+ # obtaining a copy of this software and associated documentation
28
+ # files (the "Software"), to deal in the Software without
29
+ # restriction, including without limitation the rights to use, copy,
30
+ # modify, merge, publish, distribute, sublicense, and/or sell copies
31
+ # of the Software, and to permit persons to whom the Software is
32
+ # furnished to do so, subject to the following conditions:
33
+ #
34
+ # The above copyright notice and this permission notice shall be
35
+ # included in all copies or substantial portions of the Software.
36
+ #
37
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
42
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
44
+ # DEALINGS IN THE SOFTWARE.
45
+ #
46
+ # </html5_license>
47
+ module SafeList
48
+
49
+ ACCEPTABLE_ELEMENTS = Set.new([
50
+ "a",
51
+ "abbr",
52
+ "acronym",
53
+ "address",
54
+ "area",
55
+ "article",
56
+ "aside",
57
+ "audio",
58
+ "b",
59
+ "bdi",
60
+ "bdo",
61
+ "big",
62
+ "blockquote",
63
+ "br",
64
+ "button",
65
+ "canvas",
66
+ "caption",
67
+ "center",
68
+ "cite",
69
+ "code",
70
+ "col",
71
+ "colgroup",
72
+ "command",
73
+ "datalist",
74
+ "dd",
75
+ "del",
76
+ "details",
77
+ "dfn",
78
+ "dir",
79
+ "div",
80
+ "dl",
81
+ "dt",
82
+ "em",
83
+ "fieldset",
84
+ "figcaption",
85
+ "figure",
86
+ "font",
87
+ "footer",
88
+ "form",
89
+ "h1",
90
+ "h2",
91
+ "h3",
92
+ "h4",
93
+ "h5",
94
+ "h6",
95
+ "header",
96
+ "hr",
97
+ "i",
98
+ "img",
99
+ "input",
100
+ "ins",
101
+ "kbd",
102
+ "label",
103
+ "legend",
104
+ "li",
105
+ "main",
106
+ "map",
107
+ "mark",
108
+ "menu",
109
+ "meter",
110
+ "nav",
111
+ "ol",
112
+ "optgroup",
113
+ "option",
114
+ "output",
115
+ "p",
116
+ "pre",
117
+ "q",
118
+ "s",
119
+ "samp",
120
+ "section",
121
+ "select",
122
+ "small",
123
+ "span",
124
+ "strike",
125
+ "strong",
126
+ "sub",
127
+ "summary",
128
+ "sup",
129
+ "table",
130
+ "tbody",
131
+ "td",
132
+ "textarea",
133
+ "tfoot",
134
+ "th",
135
+ "thead",
136
+ "time",
137
+ "tr",
138
+ "tt",
139
+ "u",
140
+ "ul",
141
+ "var",
142
+ "video",
143
+ ])
144
+
145
+ MATHML_ELEMENTS = Set.new([
146
+ "annotation",
147
+ "annotation-xml",
148
+ "maction",
149
+ "math",
150
+ "merror",
151
+ "mfenced",
152
+ "mfrac",
153
+ "mi",
154
+ "mmultiscripts",
155
+ "mn",
156
+ "mo",
157
+ "mover",
158
+ "mpadded",
159
+ "mphantom",
160
+ "mprescripts",
161
+ "mroot",
162
+ "mrow",
163
+ "mspace",
164
+ "msqrt",
165
+ "mstyle",
166
+ "msub",
167
+ "msubsup",
168
+ "msup",
169
+ "mtable",
170
+ "mtd",
171
+ "mtext",
172
+ "mtr",
173
+ "munder",
174
+ "munderover",
175
+ "none",
176
+ "semantics",
177
+ ])
178
+
179
+ SVG_ELEMENTS = Set.new([
180
+ "a",
181
+ "animate",
182
+ "animateColor",
183
+ "animateMotion",
184
+ "animateTransform",
185
+ "circle",
186
+ "clipPath",
187
+ "defs",
188
+ "desc",
189
+ "ellipse",
190
+ "feGaussianBlur",
191
+ "filter",
192
+ "font-face",
193
+ "font-face-name",
194
+ "font-face-src",
195
+ "foreignObject",
196
+ "g",
197
+ "glyph",
198
+ "hkern",
199
+ "line",
200
+ "linearGradient",
201
+ "marker",
202
+ "mask",
203
+ "metadata",
204
+ "missing-glyph",
205
+ "mpath",
206
+ "path",
207
+ "polygon",
208
+ "polyline",
209
+ "radialGradient",
210
+ "rect",
211
+ "set",
212
+ "stop",
213
+ "svg",
214
+ "switch",
215
+ "symbol",
216
+ "text",
217
+ "textPath",
218
+ "title",
219
+ "tspan",
220
+ "use",
221
+ ])
222
+
223
+ ACCEPTABLE_ATTRIBUTES = Set.new([
224
+ "abbr",
225
+ "accept",
226
+ "accept-charset",
227
+ "accesskey",
228
+ "action",
229
+ "align",
230
+ "alt",
231
+ "axis",
232
+ "border",
233
+ "cellpadding",
234
+ "cellspacing",
235
+ "char",
236
+ "charoff",
237
+ "charset",
238
+ "checked",
239
+ "cite",
240
+ "class",
241
+ "clear",
242
+ "color",
243
+ "cols",
244
+ "colspan",
245
+ "compact",
246
+ "contenteditable",
247
+ "coords",
248
+ "datetime",
249
+ "dir",
250
+ "disabled",
251
+ "enctype",
252
+ "for",
253
+ "frame",
254
+ "headers",
255
+ "height",
256
+ "href",
257
+ "hreflang",
258
+ "hspace",
259
+ "id",
260
+ "ismap",
261
+ "label",
262
+ "lang",
263
+ "longdesc",
264
+ "loop",
265
+ "loopcount",
266
+ "loopend",
267
+ "loopstart",
268
+ "maxlength",
269
+ "media",
270
+ "method",
271
+ "multiple",
272
+ "name",
273
+ "nohref",
274
+ "noshade",
275
+ "nowrap",
276
+ "poster",
277
+ "preload",
278
+ "prompt",
279
+ "readonly",
280
+ "rel",
281
+ "rev",
282
+ "rows",
283
+ "rowspan",
284
+ "rules",
285
+ "scope",
286
+ "selected",
287
+ "shape",
288
+ "size",
289
+ "span",
290
+ "src",
291
+ "start",
292
+ "style",
293
+ "summary",
294
+ "tabindex",
295
+ "target",
296
+ "title",
297
+ "type",
298
+ "usemap",
299
+ "valign",
300
+ "value",
301
+ "vspace",
302
+ "width",
303
+ "xml:lang",
304
+ ])
305
+
306
+ MATHML_ATTRIBUTES = Set.new([
307
+ "actiontype",
308
+ "align",
309
+ "close",
310
+ "columnalign",
311
+ "columnlines",
312
+ "columnspacing",
313
+ "columnspan",
314
+ "depth",
315
+ "display",
316
+ "displaystyle",
317
+ "encoding",
318
+ "equalcolumns",
319
+ "equalrows",
320
+ "fence",
321
+ "fontstyle",
322
+ "fontweight",
323
+ "frame",
324
+ "height",
325
+ "linethickness",
326
+ "lspace",
327
+ "mathbackground",
328
+ "mathcolor",
329
+ "mathvariant",
330
+ "maxsize",
331
+ "minsize",
332
+ "open",
333
+ "other",
334
+ "rowalign",
335
+ "rowlines",
336
+ "rowspacing",
337
+ "rowspan",
338
+ "rspace",
339
+ "scriptlevel",
340
+ "selection",
341
+ "separator",
342
+ "separators",
343
+ "stretchy",
344
+ "width",
345
+ "xlink:href",
346
+ "xlink:show",
347
+ "xlink:type",
348
+ "xmlns",
349
+ "xmlns:xlink",
350
+ ])
351
+
352
+ SVG_ATTRIBUTES = Set.new([
353
+ "accent-height",
354
+ "accumulate",
355
+ "additive",
356
+ "alphabetic",
357
+ "arabic-form",
358
+ "ascent",
359
+ "attributeName",
360
+ "attributeType",
361
+ "baseProfile",
362
+ "bbox",
363
+ "begin",
364
+ "by",
365
+ "calcMode",
366
+ "cap-height",
367
+ "class",
368
+ "clip-path",
369
+ "clip-rule",
370
+ "color",
371
+ "color-interpolation-filters",
372
+ "color-rendering",
373
+ "content",
374
+ "cx",
375
+ "cy",
376
+ "d",
377
+ "descent",
378
+ "display",
379
+ "dur",
380
+ "dx",
381
+ "dy",
382
+ "end",
383
+ "fill",
384
+ "fill-opacity",
385
+ "fill-rule",
386
+ "filterRes",
387
+ "filterUnits",
388
+ "font-family",
389
+ "font-size",
390
+ "font-stretch",
391
+ "font-style",
392
+ "font-variant",
393
+ "font-weight",
394
+ "fx",
395
+ "fy",
396
+ "g1",
397
+ "g2",
398
+ "glyph-name",
399
+ "gradientUnits",
400
+ "hanging",
401
+ "height",
402
+ "horiz-adv-x",
403
+ "horiz-origin-x",
404
+ "id",
405
+ "ideographic",
406
+ "k",
407
+ "keyPoints",
408
+ "keySplines",
409
+ "keyTimes",
410
+ "lang",
411
+ "marker-end",
412
+ "marker-mid",
413
+ "marker-start",
414
+ "markerHeight",
415
+ "markerUnits",
416
+ "markerWidth",
417
+ "maskContentUnits",
418
+ "maskUnits",
419
+ "mathematical",
420
+ "max",
421
+ "method",
422
+ "min",
423
+ "name",
424
+ "offset",
425
+ "opacity",
426
+ "orient",
427
+ "origin",
428
+ "overline-position",
429
+ "overline-thickness",
430
+ "panose-1",
431
+ "path",
432
+ "pathLength",
433
+ "patternContentUnits",
434
+ "patternTransform",
435
+ "patternUnits",
436
+ "points",
437
+ "preserveAspectRatio",
438
+ "primitiveUnits",
439
+ "r",
440
+ "refX",
441
+ "refY",
442
+ "repeatCount",
443
+ "repeatDur",
444
+ "requiredExtensions",
445
+ "requiredFeatures",
446
+ "restart",
447
+ "rotate",
448
+ "rx",
449
+ "ry",
450
+ "slope",
451
+ "spacing",
452
+ "startOffset",
453
+ "stdDeviation",
454
+ "stemh",
455
+ "stemv",
456
+ "stop-color",
457
+ "stop-opacity",
458
+ "strikethrough-position",
459
+ "strikethrough-thickness",
460
+ "stroke",
461
+ "stroke-dasharray",
462
+ "stroke-dashoffset",
463
+ "stroke-linecap",
464
+ "stroke-linejoin",
465
+ "stroke-miterlimit",
466
+ "stroke-opacity",
467
+ "stroke-width",
468
+ "systemLanguage",
469
+ "target",
470
+ "text-anchor",
471
+ "to",
472
+ "transform",
473
+ "type",
474
+ "u1",
475
+ "u2",
476
+ "underline-position",
477
+ "underline-thickness",
478
+ "unicode",
479
+ "unicode-range",
480
+ "units-per-em",
481
+ "values",
482
+ "version",
483
+ "viewBox",
484
+ "visibility",
485
+ "width",
486
+ "widths",
487
+ "x",
488
+ "x-height",
489
+ "x1",
490
+ "x2",
491
+ "xlink:actuate",
492
+ "xlink:arcrole",
493
+ "xlink:href",
494
+ "xlink:role",
495
+ "xlink:show",
496
+ "xlink:title",
497
+ "xlink:type",
498
+ "xml:base",
499
+ "xml:lang",
500
+ "xml:space",
501
+ "xmlns",
502
+ "xmlns:xlink",
503
+ "y",
504
+ "y1",
505
+ "y2",
506
+ "zoomAndPan",
507
+ ])
508
+
509
+ ATTR_VAL_IS_URI = Set.new([
510
+ "action",
511
+ "cite",
512
+ "href",
513
+ "longdesc",
514
+ "poster",
515
+ "preload",
516
+ "src",
517
+ "xlink:href",
518
+ "xml:base",
519
+ ])
520
+
521
+ SVG_ATTR_VAL_ALLOWS_REF = Set.new([
522
+ "clip-path",
523
+ "color-profile",
524
+ "cursor",
525
+ "fill",
526
+ "filter",
527
+ "marker",
528
+ "marker-end",
529
+ "marker-mid",
530
+ "marker-start",
531
+ "mask",
532
+ "stroke",
533
+ ])
534
+
535
+ SVG_ALLOW_LOCAL_HREF = Set.new([
536
+ "altGlyph",
537
+ "animate",
538
+ "animateColor",
539
+ "animateMotion",
540
+ "animateTransform",
541
+ "cursor",
542
+ "feImage",
543
+ "filter",
544
+ "linearGradient",
545
+ "pattern",
546
+ "radialGradient",
547
+ "set",
548
+ "textpath",
549
+ "tref",
550
+ "use",
551
+ ])
552
+
553
+ ACCEPTABLE_CSS_PROPERTIES = Set.new([
554
+ "azimuth",
555
+ "background-color",
556
+ "border-bottom-color",
557
+ "border-collapse",
558
+ "border-color",
559
+ "border-left-color",
560
+ "border-right-color",
561
+ "border-top-color",
562
+ "clear",
563
+ "color",
564
+ "cursor",
565
+ "direction",
566
+ "display",
567
+ "elevation",
568
+ "float",
569
+ "font",
570
+ "font-family",
571
+ "font-size",
572
+ "font-style",
573
+ "font-variant",
574
+ "font-weight",
575
+ "height",
576
+ "letter-spacing",
577
+ "line-height",
578
+ "list-style",
579
+ "list-style-type",
580
+ "overflow",
581
+ "pause",
582
+ "pause-after",
583
+ "pause-before",
584
+ "pitch",
585
+ "pitch-range",
586
+ "richness",
587
+ "speak",
588
+ "speak-header",
589
+ "speak-numeral",
590
+ "speak-punctuation",
591
+ "speech-rate",
592
+ "stress",
593
+ "text-align",
594
+ "text-decoration",
595
+ "text-indent",
596
+ "unicode-bidi",
597
+ "vertical-align",
598
+ "voice-family",
599
+ "volume",
600
+ "white-space",
601
+ "width",
602
+ ])
603
+
604
+ ACCEPTABLE_CSS_KEYWORDS = Set.new([
605
+ "!important",
606
+ "aqua",
607
+ "auto",
608
+ "black",
609
+ "block",
610
+ "blue",
611
+ "bold",
612
+ "both",
613
+ "bottom",
614
+ "brown",
615
+ "center",
616
+ "collapse",
617
+ "dashed",
618
+ "dotted",
619
+ "fuchsia",
620
+ "gray",
621
+ "green",
622
+ "italic",
623
+ "left",
624
+ "lime",
625
+ "maroon",
626
+ "medium",
627
+ "navy",
628
+ "none",
629
+ "normal",
630
+ "nowrap",
631
+ "olive",
632
+ "pointer",
633
+ "purple",
634
+ "red",
635
+ "right",
636
+ "silver",
637
+ "solid",
638
+ "teal",
639
+ "thin",
640
+ "thick",
641
+ "top",
642
+ "transparent",
643
+ "underline",
644
+ "white",
645
+ "yellow",
646
+ ])
647
+
648
+ # see https://www.quackit.com/css/functions/
649
+ # omit `url` and `image` from that list
650
+ ACCEPTABLE_CSS_FUNCTIONS = Set.new([
651
+ "attr",
652
+ "blur",
653
+ "brightness",
654
+ "calc",
655
+ "circle",
656
+ "contrast",
657
+ "counter",
658
+ "counters",
659
+ "cubic-bezier",
660
+ "drop-shadow",
661
+ "ellipse",
662
+ "grayscale",
663
+ "hsl",
664
+ "hsla",
665
+ "hue-rotate",
666
+ "hwb",
667
+ "inset",
668
+ "invert",
669
+ "linear-gradient",
670
+ "matrix",
671
+ "matrix3d",
672
+ "opacity",
673
+ "perspective",
674
+ "polygon",
675
+ "radial-gradient",
676
+ "repeating-linear-gradient",
677
+ "repeating-radial-gradient",
678
+ "rgb",
679
+ "rgba",
680
+ "rotate",
681
+ "rotate3d",
682
+ "rotateX",
683
+ "rotateY",
684
+ "rotateZ",
685
+ "saturate",
686
+ "sepia",
687
+ "scale",
688
+ "scale3d",
689
+ "scaleX",
690
+ "scaleY",
691
+ "scaleZ",
692
+ "skew",
693
+ "skewX",
694
+ "skewY",
695
+ "symbols",
696
+ "translate",
697
+ "translate3d",
698
+ "translateX",
699
+ "translateY",
700
+ "translateZ",
701
+ ])
702
+
703
+ SHORTHAND_CSS_PROPERTIES = Set.new([
704
+ "background",
705
+ "border",
706
+ "margin",
707
+ "padding",
708
+ ])
709
+
710
+ ACCEPTABLE_SVG_PROPERTIES = Set.new([
711
+ "fill",
712
+ "fill-opacity",
713
+ "fill-rule",
714
+ "stroke",
715
+ "stroke-width",
716
+ "stroke-linecap",
717
+ "stroke-linejoin",
718
+ "stroke-opacity",
719
+ ])
720
+
721
+ PROTOCOL_SEPARATOR = /:|(&#0*58)|(&#x70)|(&#x0*3a)|(%|&#37;)3A/i
722
+
723
+ ACCEPTABLE_PROTOCOLS = Set.new([
724
+ "afs",
725
+ "aim",
726
+ "callto",
727
+ "data",
728
+ "ed2k",
729
+ "feed",
730
+ "ftp",
731
+ "gopher",
732
+ "http",
733
+ "https",
734
+ "irc",
735
+ "line",
736
+ "mailto",
737
+ "news",
738
+ "nntp",
739
+ "rsync",
740
+ "rtsp",
741
+ "sftp",
742
+ "ssh",
743
+ "tag",
744
+ "tel",
745
+ "telnet",
746
+ "urn",
747
+ "webcal",
748
+ "xmpp",
749
+ ])
750
+
751
+ ACCEPTABLE_URI_DATA_MEDIATYPES = Set.new([
752
+ "image/gif",
753
+ "image/jpeg",
754
+ "image/png",
755
+ "image/svg+xml",
756
+ "text/css",
757
+ "text/plain",
758
+ ])
759
+
760
+ # subclasses may define their own versions of these constants
761
+ ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS
762
+ ALLOWED_ATTRIBUTES = ACCEPTABLE_ATTRIBUTES + MATHML_ATTRIBUTES + SVG_ATTRIBUTES
763
+ ALLOWED_CSS_PROPERTIES = ACCEPTABLE_CSS_PROPERTIES
764
+ ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS
765
+ ALLOWED_CSS_FUNCTIONS = ACCEPTABLE_CSS_FUNCTIONS
766
+ ALLOWED_SVG_PROPERTIES = ACCEPTABLE_SVG_PROPERTIES
767
+ ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS
768
+ ALLOWED_URI_DATA_MEDIATYPES = ACCEPTABLE_URI_DATA_MEDIATYPES
769
+
770
+ VOID_ELEMENTS = Set.new([
771
+ "area",
772
+ "base",
773
+ "br",
774
+ "col",
775
+ "embed",
776
+ "hr",
777
+ "img",
778
+ "input",
779
+ "link",
780
+ "meta",
781
+ "param",
782
+ ])
783
+
784
+ # additional tags we should consider safe since we have libxml2 fixing up our documents.
785
+ TAGS_SAFE_WITH_LIBXML2 = Set.new([
786
+ "body",
787
+ "head",
788
+ "html",
789
+ ])
790
+ ALLOWED_ELEMENTS_WITH_LIBXML2 = ALLOWED_ELEMENTS + TAGS_SAFE_WITH_LIBXML2
791
+ end
792
+
793
+ WhiteList = SafeList
794
+ if Object.respond_to?(:deprecate_constant)
795
+ deprecate_constant :WhiteList
796
+ end
797
+
798
+ ::Loofah::MetaHelpers.add_downcased_set_members_to_all_set_constants ::Loofah::HTML5::SafeList
799
+ end
800
+ end