File: CVE-2018-8048.patch

package info (click to toggle)
ruby-loofah 2.0.3-2%2Bdeb9u3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 500 kB
  • sloc: ruby: 1,972; makefile: 2
file content (99 lines) | stat: -rw-r--r-- 3,694 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Description: Patch to address potential XSS vuln (CVE-2018-8048)
  libxml2 >= 2.9.2 fails to escape comments within some attributes. It
  wants to ensure these comments can be treated as "server-side
  includes", but as a result fails to ensure that serialization is
  well-formed, resulting in an opportunity for XSS injection of code
  into a final re-parsed document (presumably in a browser).
Origin: upstream
Debian-Bug: #893596
Applied-Upstream: https://github.com/flavorjones/loofah/commit/4a08c25a603654f2fc505a7d2bf0c35a39870ad7
Last-Update: 2018-03-25
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/lib/loofah.rb
+++ b/lib/loofah.rb
@@ -6,6 +6,7 @@
 require 'loofah/elements'
 
 require 'loofah/html5/whitelist'
+require 'loofah/html5/libxml2_workarounds'
 require 'loofah/html5/scrub'
 
 require 'loofah/scrubber'
--- /dev/null
+++ b/lib/loofah/html5/libxml2_workarounds.rb
@@ -0,0 +1,12 @@
+require 'set'
+module Loofah
+  module LibxmlWorkarounds
+    BROKEN_ESCAPING_ATTRIBUTES = Set.new %w[
+        href
+        action
+        src
+        name
+      ]
+    BROKEN_ESCAPING_ATTRIBUTES_QUALIFYING_TAG = {"name" => "a"}
+  end
+end
--- a/lib/loofah/html5/scrub.rb
+++ b/lib/loofah/html5/scrub.rb
@@ -54,6 +54,7 @@
           node.attribute_nodes.each do |attr_node|
             node.remove_attribute(attr_node.name) if attr_node.value !~ /[^[:space:]]/
           end
+          force_correct_attribute_escaping! node
         end
 
         def scrub_css_attribute node
@@ -89,6 +90,18 @@
           style = clean.join(' ')
         end
 
+        def force_correct_attribute_escaping! node
+          return unless Nokogiri::VersionInfo.instance.libxml2?
+          node.attribute_nodes.each do |attr_node|
+            next unless LibxmlWorkarounds::BROKEN_ESCAPING_ATTRIBUTES.include?(attr_node.name)
+            tag_name = LibxmlWorkarounds::BROKEN_ESCAPING_ATTRIBUTES_QUALIFYING_TAG[attr_node.name]
+            next unless tag_name.nil? || tag_name == node.name
+            encoding = attr_node.value.encoding
+            attr_node.value = attr_node.value.gsub(/[ "]/) do |m|
+              '%' + m.unpack('H2' * m.bytesize).join('%').upcase
+            end.force_encoding(encoding)
+          end
+        end
       end
 
     end
--- a/test/integration/test_ad_hoc.rb
+++ b/test/integration/test_ad_hoc.rb
@@ -173,4 +173,30 @@
     html = "<p>Foo</p>\n<p>Bar</p>"
     assert_equal "Foo\nBar", Loofah.scrub_document(html, :prune).text
   end
+	[
+      {tag: "a",   attr: "href"},
+      {tag: "div", attr: "href"},
+      {tag: "a",   attr: "action"},
+      {tag: "div", attr: "action"},
+      {tag: "a",   attr: "src"},
+      {tag: "div", attr: "src"},
+      {tag: "a",   attr: "name"},
+      {tag: "div", attr: "name", unescaped: true},
+    ].each do |config|
+      define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do
+        html = %{<#{config[:tag]} #{config[:attr]}='examp<!--" unsafeattr=foo()>-->le.com'>test</#{config[:tag]}>}
+        reparsed = Loofah.fragment(Loofah.fragment(html).scrub!(:prune).to_html)
+        attributes = reparsed.at_css(config[:tag]).attribute_nodes
+        assert_equal [config[:attr]], attributes.collect(&:name)
+        if Nokogiri::VersionInfo.new.libxml2?
+          if config[:unescaped]
+            assert_equal %{examp<!--" unsafeattr=foo()>-->le.com}, attributes.first.value
+          else
+            assert_equal %{examp<!--%22%20unsafeattr=foo()>-->le.com}, attributes.first.value
+          end
+        else
+          assert_equal %{examp<!--%22 unsafeattr=foo()>-->le.com}, attributes.first.value
+        end
+      end
+    end
 end