tobmatth/rack-ssl-enforcer — pull request #67 by tilthouse (2014-03-06 20:08:44+00:00)
Title: URI encode before passing to URI object to deal with pathological URIs

We found an issue with pathological URLs causing rack-ssl-enforcer to blow up. Our Airbrake reported the following errors:

URI::InvalidURIError: bad URI(is not URI?): http://example.org/index.php?news7["functions"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/[path]/mybic_server.php?file=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/sys/code/box.inc.php?config["sipssys"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/addvip.php?msetstr["PROGSDIR"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/index.php?config["sipssys"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/search/submit.php?config["sipssys"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/readmore.php?config["sipssys"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/search.php?config["sipssys"]=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/BsiliX_path]/files/mbox-action.php3?BSX_LIBDIR=http://www.google.com/humans.txt?
URI::InvalidURIError: bad URI(is not URI?): http://example.org/[path]/previewtheme.php?theme=1&inc_path=http://www.google.com/humans.txt?cmd
URI::InvalidURIError: bad URI(is not URI?): http://example.org/[path]/previewtheme.php?theme=1&inc_path=cmdhttp://www.google.com/humans.txt?

I have added calls to `URI.encode()` everywhere I new URI object is created, which should fix the issue.

As an aside, I tried adding a test:

context 'problematic URI parsing' do
setup { mock_app }
should 'not raise an exception parsing crazy URIs' do
get 'http://example.org/sys/code/box.inc.php?config["sipssys"]=http://www.google.com/humans.txt?'
assert_equal 301, last_response.status
end
end

However, this doesn't work well because the `get` call itself in the test blows up trying to parse the URI.