File: 02_fix_CVE-2013-1812.patch

package info (click to toggle)
ruby-openid 2.1.8debian-6
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,676 kB
  • sloc: ruby: 16,506; xml: 219; sh: 24; makefile: 2
file content (118 lines) | stat: -rw-r--r-- 3,754 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Description: limit fetching file size & disable XML entity expansion
  This prevents possible XML denial of service attacks [CVE-2013-1812]
Author: nov matake <nov@matake.jp>
Origin: https://github.com/openid/ruby-openid/commit/a3693cef06049563f5b4e4824f4d3211288508ed
Bug: https://github.com/openid/ruby-openid/pull/43
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702217
Reviewed-by: Cédric Boutillier <boutil@debian.org>
Last-Update: 2012-10-23

---
 lib/openid/fetchers.rb   |   17 ++++++++++++++---
 lib/openid/yadis/xrds.rb |   34 ++++++++++++++++++++++------------
 2 files changed, 36 insertions(+), 15 deletions(-)

--- a/lib/openid/fetchers.rb
+++ b/lib/openid/fetchers.rb
@@ -10,7 +10,7 @@
   require 'net/http'
 end
 
-MAX_RESPONSE_KB = 1024
+MAX_RESPONSE_KB = 10485760 # 10 MB (can be smaller, I guess)
 
 module Net
   class HTTP
@@ -192,6 +192,16 @@
         conn = make_connection(url)
         response = nil
 
+        whole_body = ''
+        body_size_limitter = lambda do |r|
+          r.read_body do |partial|   # read body now
+            whole_body << partial
+            if whole_body.length > MAX_RESPONSE_KB
+              raise FetchingError.new("Response Too Large")
+            end
+          end
+          whole_body
+        end
         response = conn.start {
           # Check the certificate against the URL's hostname
           if supports_ssl?(conn) and conn.use_ssl?
@@ -199,13 +209,12 @@
           end
 
           if body.nil?
-            conn.request_get(url.request_uri, headers)
+            conn.request_get(url.request_uri, headers, &body_size_limitter)
           else
             headers["Content-type"] ||= "application/x-www-form-urlencoded"
-            conn.request_post(url.request_uri, body, headers)
+            conn.request_post(url.request_uri, body, headers, &body_size_limitter)
           end
         }
-        setup_encoding(response)
       rescue Timeout::Error => why
         raise FetchingError, "Error fetching #{url}: #{why}"
       rescue RuntimeError => why
@@ -232,7 +241,10 @@
           raise FetchingError, "Error encountered in redirect from #{url}: #{why}"
         end
       else
-        return HTTPResponse._from_net_response(response, unparsed_url)
+        response = HTTPResponse._from_net_response(response, unparsed_url)
+        response.body = whole_body
+        setup_encoding(response)
+        return response
       end
     end
 
--- a/lib/openid/yadis/xrds.rb
+++ b/lib/openid/yadis/xrds.rb
@@ -88,23 +88,33 @@
     end
 
     def Yadis::parseXRDS(text)
-      if text.nil?
-        raise XRDSError.new("Not an XRDS document.")
-      end
+      disable_entity_expansion do
+        if text.nil?
+          raise XRDSError.new("Not an XRDS document.")
+        end
 
-      begin
-        d = REXML::Document.new(text)
-      rescue RuntimeError => why
-        raise XRDSError.new("Not an XRDS document. Failed to parse XML.")
-      end
+        begin
+          d = REXML::Document.new(text)
+        rescue RuntimeError => why
+          raise XRDSError.new("Not an XRDS document. Failed to parse XML.")
+        end
 
-      if is_xrds?(d)
-        return d
-      else
-        raise XRDSError.new("Not an XRDS document.")
+        if is_xrds?(d)
+          return d
+        else
+          raise XRDSError.new("Not an XRDS document.")
+        end
       end
     end
 
+    def Yadis::disable_entity_expansion
+      _previous_ = REXML::Document::entity_expansion_limit
+      REXML::Document::entity_expansion_limit = 0
+      yield
+    ensure
+      REXML::Document::entity_expansion_limit = _previous_
+    end
+
     def Yadis::is_xrds?(xrds_tree)
       xrds_root = xrds_tree.root
       return (!xrds_root.nil? and