Ruby's open-uri fails when handling secure redirections

I've realised that when the target server responds with a redirection to a https uri, ruby fails with the message:

(RuntimeError) redirection forbidden:
http://hudson.gotdns.com/latest/hudson.war
-> https://hudson.dev.java.net/files/documents/2402/142380/hudson.war
[...]/ruby/1.8/open-uri.rb:174:in `open_loop'
[...]/ruby/1.8/open-uri.rb:132:in `open_uri'



It's due to a paranoid check that rails do to avoid redirections to private stuff like 'file://'. But, this check uses a incomplete regular expression:


[...]
unless OpenURI.redirectable?(uri, redirect)
raise "redirection forbidden: #{uri} -> #{redirect}"
end
[...]

def OpenURI.redirectable?(uri1, uri2) # :nodoc:
# This test is intended to forbid a redirection from http://... to
# file:///etc/passwd.
# However this is ad hoc. It should be extensible/configurable.
uri1.scheme.downcase == uri2.scheme.downcase ||
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
end



I've opened a ticket and sent a patch to the ruby core team reporting this issue.

But the questions are: is this check needed?, why don't check just the presence of file:// in the url?

3 comentarios:

Anonymous said...

> But the questions are: is this check needed?, why don't check just the presence of file:// in the url?

The check is needed, absolutely. Whitelisting is more secure than blacklisting. If some string or character escape was found that passed the regex but was interpreted as file:// by the system, then Ruby would have a serious security problem on its hands.

Manolo said...

I disagree, if you just want not redirect 'file://' check that because it is the only protocol valid in the URI for a local file in the system. The other way means that you are making false assumptions about ruby being insecure that you have to protect it coding hacks like this which could break things.
Note that no other http client libraries does this (take a look to java:commons-http-client or perl:lwp)
So I'd rather have a way to specify the protocols to allow/disallow instead of patching the sources.

Anonymous said...

It should be up to the developer using open-uri

Post a Comment