Permalink
Browse files

Merge pull request #43 from nov/against_dos

limit fetching file size & disable XML entity expansion
  • Loading branch information...
2 parents 578d3b0 + 3540a51 commit a3693cef06049563f5b4e4824f4d3211288508ed @dennisreimann dennisreimann committed Oct 23, 2012
Showing with 39 additions and 17 deletions.
  1. +17 −5 lib/openid/fetchers.rb
  2. +22 −12 lib/openid/yadis/xrds.rb
View
@@ -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,20 +192,29 @@ def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
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?
conn.post_connection_check(url.host)
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 @@ def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
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
View
@@ -88,23 +88,33 @@ class XRDSError < StandardError
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

0 comments on commit a3693ce

Please sign in to comment.