loofah 2.2.0 → 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.

@@ -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