loofah 2.17.0 → 2.19.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7312c8a91f201016ceb465888c38c9a6e4f93ba362f1112a3f9d657bdb31e759
4
- data.tar.gz: 47f2057c2ebce823f44ae997cdd5f3eba672d14c25ebd3176a54dd241573e7a5
3
+ metadata.gz: bd3edb0acdf2359d82564aca0bc13710d9f6c49157963d18953ff55bd7c14413
4
+ data.tar.gz: 3a6e11b7deb9cfb469aaf6ec919062687bd4215ef11980bded72ca298807610c
5
5
  SHA512:
6
- metadata.gz: a5ba0f513d4cb58450f3fdcbe178d266f51ae9f07ae0e8a64813b348c987c292aed10078a2de71ef0311efcd916b2e9c3b29df20eef61e8f242b2f4192a25748
7
- data.tar.gz: 544bae277ff7a5ccf8d2f2820fec7db49d6157a4cf31d95d209d74e3de99e76fa0e2bd720c903830191f49756e62fa2d6fc6c0b23a1c76882b43f1e38372e4a5
6
+ metadata.gz: 4970a6aa72265f60556dd6fd254375c86d3f83be23f3bbcc8b04df00ce0e801e8ef9e67d0a77ca6a21915be89226131c16a7f3540f02538cc2b9a369950dfebf
7
+ data.tar.gz: 27e3a06cc391ec3d9e3c966efdb6b4ce58e98c397ec87490d418406c17757e5cb0193edabaced30a9f24320c729e6730308e346610859f9f7c6d5fcc6f72cd56
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.19.1 / 2022-12-13
4
+
5
+ ### Security
6
+
7
+ * Address CVE-2022-23514, inefficient regular expression complexity. See [GHSA-486f-hjj9-9vhh](https://github.com/flavorjones/loofah/security/advisories/GHSA-486f-hjj9-9vhh) for more information.
8
+ * Address CVE-2022-23515, improper neutralization of data URIs. See [GHSA-228g-948r-83gx](https://github.com/flavorjones/loofah/security/advisories/GHSA-228g-948r-83gx) for more information.
9
+ * Address CVE-2022-23516, uncontrolled recursion. See [GHSA-3x8r-x6xp-q4vm](https://github.com/flavorjones/loofah/security/advisories/GHSA-3x8r-x6xp-q4vm) for more information.
10
+
11
+
12
+ ## 2.19.0 / 2022-09-14
13
+
14
+ ### Features
15
+
16
+ * Allow SVG 1.0 color keyword names in CSS attributes. These colors are part of the [CSS Color Module Level 3](https://www.w3.org/TR/css-color-3/#svg-color) recommendation released 2022-01-18. [[#243](https://github.com/flavorjones/loofah/issues/243)]
17
+
18
+
19
+ ## 2.18.0 / 2022-05-11
20
+
21
+ ### Features
22
+
23
+ * Allow CSS property `aspect-ratio`. [[#236](https://github.com/flavorjones/loofah/issues/236)] (Thanks, [@louim](https://github.com/louim)!)
24
+
25
+
3
26
  ## 2.17.0 / 2022-04-28
4
27
 
5
28
  ### Features
data/README.md CHANGED
@@ -348,7 +348,7 @@ And a big shout-out to Corey Innis for the name, and feedback on the API.
348
348
 
349
349
  ## Thank You
350
350
 
351
- The following people have generously donated via the [Pledgie](http://pledgie.com) badge on the [Loofah github page](https://github.com/flavorjones/loofah):
351
+ The following people have generously funded Loofah:
352
352
 
353
353
  * Bill Harding
354
354
 
@@ -617,6 +617,7 @@ module Loofah
617
617
  "align-content",
618
618
  "align-items",
619
619
  "align-self",
620
+ "aspect-ratio",
620
621
  "background-color",
621
622
  "border-bottom-color",
622
623
  "border-collapse",
@@ -683,23 +684,16 @@ module Loofah
683
684
 
684
685
  ACCEPTABLE_CSS_KEYWORDS = Set.new([
685
686
  "!important",
686
- "aqua",
687
687
  "auto",
688
- "black",
689
688
  "block",
690
- "blue",
691
689
  "bold",
692
690
  "both",
693
691
  "bottom",
694
- "brown",
695
692
  "center",
696
693
  "collapse",
697
694
  "dashed",
698
695
  "dotted",
699
696
  "double",
700
- "fuchsia",
701
- "gray",
702
- "green",
703
697
  "groove",
704
698
  "hidden",
705
699
  "inherit",
@@ -707,35 +701,196 @@ module Loofah
707
701
  "inset",
708
702
  "italic",
709
703
  "left",
710
- "lime",
711
- "maroon",
712
704
  "medium",
713
- "navy",
714
705
  "none",
715
706
  "normal",
716
707
  "nowrap",
717
- "olive",
718
708
  "outset",
719
709
  "pointer",
720
- "purple",
721
- "red",
722
710
  "revert",
723
711
  "ridge",
724
712
  "right",
725
713
  "separate",
726
- "silver",
727
714
  "solid",
728
- "teal",
729
715
  "thick",
730
716
  "thin",
731
717
  "top",
732
718
  "transparent",
733
719
  "underline",
734
720
  "unset",
735
- "white",
736
- "yellow",
737
721
  ])
738
722
 
723
+ # https://www.w3.org/TR/css-color-3/#html4
724
+ ACCEPTABLE_CSS_COLORS = Set.new([
725
+ "aqua",
726
+ "black",
727
+ "blue",
728
+ "fuchsia",
729
+ "gray",
730
+ "green",
731
+ "lime",
732
+ "maroon",
733
+ "navy",
734
+ "olive",
735
+ "purple",
736
+ "red",
737
+ "silver",
738
+ "teal",
739
+ "white",
740
+ "yellow",
741
+ ])
742
+
743
+ # https://www.w3.org/TR/css-color-3/#svg-color
744
+ ACCEPTABLE_CSS_EXTENDED_COLORS = Set.new([
745
+ "aliceblue",
746
+ "antiquewhite",
747
+ "aqua",
748
+ "aquamarine",
749
+ "azure",
750
+ "beige",
751
+ "bisque",
752
+ "black",
753
+ "blanchedalmond",
754
+ "blue",
755
+ "blueviolet",
756
+ "brown",
757
+ "burlywood",
758
+ "cadetblue",
759
+ "chartreuse",
760
+ "chocolate",
761
+ "coral",
762
+ "cornflowerblue",
763
+ "cornsilk",
764
+ "crimson",
765
+ "cyan",
766
+ "darkblue",
767
+ "darkcyan",
768
+ "darkgoldenrod",
769
+ "darkgray",
770
+ "darkgreen",
771
+ "darkgrey",
772
+ "darkkhaki",
773
+ "darkmagenta",
774
+ "darkolivegreen",
775
+ "darkorange",
776
+ "darkorchid",
777
+ "darkred",
778
+ "darksalmon",
779
+ "darkseagreen",
780
+ "darkslateblue",
781
+ "darkslategray",
782
+ "darkslategrey",
783
+ "darkturquoise",
784
+ "darkviolet",
785
+ "deeppink",
786
+ "deepskyblue",
787
+ "dimgray",
788
+ "dimgrey",
789
+ "dodgerblue",
790
+ "firebrick",
791
+ "floralwhite",
792
+ "forestgreen",
793
+ "fuchsia",
794
+ "gainsboro",
795
+ "ghostwhite",
796
+ "gold",
797
+ "goldenrod",
798
+ "gray",
799
+ "green",
800
+ "greenyellow",
801
+ "grey",
802
+ "honeydew",
803
+ "hotpink",
804
+ "indianred",
805
+ "indigo",
806
+ "ivory",
807
+ "khaki",
808
+ "lavender",
809
+ "lavenderblush",
810
+ "lawngreen",
811
+ "lemonchiffon",
812
+ "lightblue",
813
+ "lightcoral",
814
+ "lightcyan",
815
+ "lightgoldenrodyellow",
816
+ "lightgray",
817
+ "lightgreen",
818
+ "lightgrey",
819
+ "lightpink",
820
+ "lightsalmon",
821
+ "lightseagreen",
822
+ "lightskyblue",
823
+ "lightslategray",
824
+ "lightslategrey",
825
+ "lightsteelblue",
826
+ "lightyellow",
827
+ "lime",
828
+ "limegreen",
829
+ "linen",
830
+ "magenta",
831
+ "maroon",
832
+ "mediumaquamarine",
833
+ "mediumblue",
834
+ "mediumorchid",
835
+ "mediumpurple",
836
+ "mediumseagreen",
837
+ "mediumslateblue",
838
+ "mediumspringgreen",
839
+ "mediumturquoise",
840
+ "mediumvioletred",
841
+ "midnightblue",
842
+ "mintcream",
843
+ "mistyrose",
844
+ "moccasin",
845
+ "navajowhite",
846
+ "navy",
847
+ "oldlace",
848
+ "olive",
849
+ "olivedrab",
850
+ "orange",
851
+ "orangered",
852
+ "orchid",
853
+ "palegoldenrod",
854
+ "palegreen",
855
+ "paleturquoise",
856
+ "palevioletred",
857
+ "papayawhip",
858
+ "peachpuff",
859
+ "peru",
860
+ "pink",
861
+ "plum",
862
+ "powderblue",
863
+ "purple",
864
+ "red",
865
+ "rosybrown",
866
+ "royalblue",
867
+ "saddlebrown",
868
+ "salmon",
869
+ "sandybrown",
870
+ "seagreen",
871
+ "seashell",
872
+ "sienna",
873
+ "silver",
874
+ "skyblue",
875
+ "slateblue",
876
+ "slategray",
877
+ "slategrey",
878
+ "snow",
879
+ "springgreen",
880
+ "steelblue",
881
+ "tan",
882
+ "teal",
883
+ "thistle",
884
+ "tomato",
885
+ "turquoise",
886
+ "violet",
887
+ "wheat",
888
+ "white",
889
+ "whitesmoke",
890
+ "yellow",
891
+ "yellowgreen",
892
+ ])
893
+
739
894
  # see https://www.quackit.com/css/functions/
740
895
  # omit `url` and `image` from that list
741
896
  ACCEPTABLE_CSS_FUNCTIONS = Set.new([
@@ -844,7 +999,6 @@ module Loofah
844
999
  "image/gif",
845
1000
  "image/jpeg",
846
1001
  "image/png",
847
- "image/svg+xml",
848
1002
  "text/css",
849
1003
  "text/plain",
850
1004
  ])
@@ -853,7 +1007,7 @@ module Loofah
853
1007
  ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS
854
1008
  ALLOWED_ATTRIBUTES = ACCEPTABLE_ATTRIBUTES + MATHML_ATTRIBUTES + SVG_ATTRIBUTES + ARIA_ATTRIBUTES
855
1009
  ALLOWED_CSS_PROPERTIES = ACCEPTABLE_CSS_PROPERTIES
856
- ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS
1010
+ ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS + ACCEPTABLE_CSS_COLORS + ACCEPTABLE_CSS_EXTENDED_COLORS
857
1011
  ALLOWED_CSS_FUNCTIONS = ACCEPTABLE_CSS_FUNCTIONS
858
1012
  ALLOWED_SVG_PROPERTIES = ACCEPTABLE_SVG_PROPERTIES
859
1013
  ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS
@@ -36,24 +36,13 @@ module Loofah
36
36
  end
37
37
 
38
38
  if SafeList::ATTR_VAL_IS_URI.include?(attr_name)
39
- # this block lifted nearly verbatim from HTML5 sanitization
40
- val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS, "").downcase
41
- if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !SafeList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0])
42
- attr_node.remove
43
- next
44
- elsif val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0] == "data"
45
- # permit only allowed data mediatypes
46
- mediatype = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[1]
47
- mediatype, _ = mediatype.split(";")[0..1] if mediatype
48
- if mediatype && !SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
49
- attr_node.remove
50
- next
51
- end
52
- end
39
+ next if scrub_uri_attribute(attr_node)
53
40
  end
41
+
54
42
  if SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
55
- attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, " ") if attr_node.value
43
+ scrub_attribute_that_allows_local_ref(attr_node)
56
44
  end
45
+
57
46
  if SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == "xlink:href" && attr_node.value =~ /^\s*[^#\s].*/m
58
47
  attr_node.remove
59
48
  next
@@ -127,6 +116,47 @@ module Loofah
127
116
  Crass::Parser.stringify(sanitized_tree)
128
117
  end
129
118
 
119
+ def scrub_attribute_that_allows_local_ref(attr_node)
120
+ return unless attr_node.value
121
+
122
+ nodes = Crass::Parser.new(attr_node.value).parse_component_values
123
+
124
+ values = nodes.map do |node|
125
+ case node[:node]
126
+ when :url
127
+ if node[:value].start_with?("#")
128
+ node[:raw]
129
+ else
130
+ nil
131
+ end
132
+ when :hash, :ident, :string
133
+ node[:raw]
134
+ else
135
+ nil
136
+ end
137
+ end.compact
138
+
139
+ attr_node.value = values.join(" ")
140
+ end
141
+
142
+ def scrub_uri_attribute(attr_node)
143
+ # this block lifted nearly verbatim from HTML5 sanitization
144
+ val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS, "").downcase
145
+ if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !SafeList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0])
146
+ attr_node.remove
147
+ return true
148
+ elsif val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0] == "data"
149
+ # permit only allowed data mediatypes
150
+ mediatype = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[1]
151
+ mediatype, _ = mediatype.split(";")[0..1] if mediatype
152
+ if mediatype && !SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
153
+ attr_node.remove
154
+ return true
155
+ end
156
+ end
157
+ false
158
+ end
159
+
130
160
  #
131
161
  # libxml2 >= 2.9.2 fails to escape comments within some attributes.
132
162
  #
@@ -152,6 +182,46 @@ module Loofah
152
182
  end.force_encoding(encoding)
153
183
  end
154
184
  end
185
+
186
+ def cdata_needs_escaping?(node)
187
+ # Nokogiri's HTML4 parser on JRuby doesn't flag the child of a `style` or `script` tag as cdata, but it acts that way
188
+ node.cdata? || (Nokogiri.jruby? && node.text? && (node.parent.name == "style" || node.parent.name == "script"))
189
+ end
190
+
191
+ def cdata_escape(node)
192
+ escaped_text = escape_tags(node.text)
193
+ if Nokogiri.jruby?
194
+ node.document.create_text_node(escaped_text)
195
+ else
196
+ node.document.create_cdata(escaped_text)
197
+ end
198
+ end
199
+
200
+ TABLE_FOR_ESCAPE_HTML__ = {
201
+ '<' => '&lt;',
202
+ '>' => '&gt;',
203
+ '&' => '&amp;',
204
+ }
205
+
206
+ def escape_tags(string)
207
+ # modified version of CGI.escapeHTML from ruby 3.1
208
+ enc = string.encoding
209
+ unless enc.ascii_compatible?
210
+ if enc.dummy?
211
+ origenc = enc
212
+ enc = Encoding::Converter.asciicompat_encoding(enc)
213
+ string = enc ? string.encode(enc) : string.b
214
+ end
215
+ table = Hash[TABLE_FOR_ESCAPE_HTML__.map {|pair|pair.map {|s|s.encode(enc)}}]
216
+ string = string.gsub(/#{"[<>&]".encode(enc)}/, table)
217
+ string.encode!(origenc) if origenc
218
+ string
219
+ else
220
+ string = string.b
221
+ string.gsub!(/[<>&]/, TABLE_FOR_ESCAPE_HTML__)
222
+ string.force_encoding(enc)
223
+ end
224
+ end
155
225
  end
156
226
  end
157
227
  end
@@ -108,6 +108,10 @@ module Loofah
108
108
  return Scrubber::CONTINUE
109
109
  end
110
110
  when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE
111
+ if HTML5::Scrub.cdata_needs_escaping?(node)
112
+ node.before(HTML5::Scrub.cdata_escape(node))
113
+ return Scrubber::STOP
114
+ end
111
115
  return Scrubber::CONTINUE
112
116
  end
113
117
  Scrubber::STOP
@@ -100,13 +100,9 @@ module Loofah
100
100
 
101
101
  def scrub(node)
102
102
  return CONTINUE if html5lib_sanitize(node) == CONTINUE
103
- if node.children.length == 1 && node.children.first.cdata?
104
- sanitized_text = Loofah.fragment(node.children.first.to_html).scrub!(:strip).to_html
105
- node.before Nokogiri::XML::Text.new(sanitized_text, node.document)
106
- else
107
- node.before node.children
108
- end
103
+ node.before(node.children)
109
104
  node.remove
105
+ return STOP
110
106
  end
111
107
  end
112
108
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Loofah
3
3
  # The version of Loofah you are using
4
- VERSION = "2.17.0"
4
+ VERSION = "2.19.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loofah
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.0
4
+ version: 2.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Dalessio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-04-28 00:00:00.000000000 Z
12
+ date: 2022-12-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: crass
@@ -199,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
199
  - !ruby/object:Gem::Version
200
200
  version: '0'
201
201
  requirements: []
202
- rubygems_version: 3.3.5
202
+ rubygems_version: 3.3.7
203
203
  signing_key:
204
204
  specification_version: 4
205
205
  summary: Loofah is a general library for manipulating and transforming HTML/XML documents