Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paths beginning with // should not be allowed when authority is present #240

Closed
clayton-shopify opened this issue Sep 20, 2016 · 4 comments
Assignees
Labels

Comments

@clayton-shopify
Copy link

According to RFC 3986 section 3.3:

If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//").

But Addressable allows such paths, which will be ambiguously interpreted as a host:

irb(main):001:0> require 'addressable/uri'
=> true

irb(main):002:0> u1 = Addressable::URI.parse('/..//example.com')
=> #<Addressable::URI:0x3ff6becfbb5c URI:/..//example.com>

irb(main):003:0> u1.normalize!
=> #<Addressable::URI:0x3ff6becfbb5c URI://example.com>

irb(main):004:0> u1.host
=> nil

irb(main):005:0> u1.path
=> "//example.com"

irb(main):006:0> u2 = Addressable::URI.parse(u1.to_s)
=> #<Addressable::URI:0x3ff6bec436b0 URI://example.com>

irb(main):007:0> u2.host
=> "example.com"

irb(main):008:0> u2.path
=> ""

This could allow URL validation logic to be bypassed.

@sporkmonger
Copy link
Owner

Interesting. Addressable uses the dotted path resolution algorithm described by RFC 3986, but apparently in this case, that results in a // prefix on the path name. I'd be inclined to raise an exception as soon as you normalized rather than normalizing paths in a way that deviates from the spec.

@sporkmonger sporkmonger self-assigned this Nov 3, 2016
@clayton-shopify
Copy link
Author

That sounds like a good approach.

Of course, normalize isn't the only way you can end up in this situation:

irb(main):001:0> require 'addressable/uri'
=> true
irb(main):002:0> u1 = Addressable::URI.new
=> #<Addressable::URI:0x3fd881114f74 URI:>
irb(main):003:0> u1.path = '//example.com'
=> "//example.com"
irb(main):004:0> u1.host
=> nil
irb(main):005:0> u2 = Addressable::URI.parse(u1.to_s)
=> #<Addressable::URI:0x3fd8810e1638 URI://example.com>
irb(main):006:0> u2.host
=> "example.com"
irb(main):007:0> u2.path
=> ""

@sporkmonger
Copy link
Owner

Yup, the validate method already addresses the multiple ways you can end up there.

@sporkmonger
Copy link
Owner

Although I did discover it wasn't correctly being called from the path= setter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants