Wednesday, September 2, 2009

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:
[...]/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}"

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)

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?