-
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Path incorrectly decoded during clean #10
Comments
I'm OK with a PR to use |
The cleaning code is fine and I agree it mirrors net/http, I think the problem is you are cleaning and setting req.URL.Path and not req.URL.RawPath. This makes RawPath an invalid escaping of Path and thus causes url.String() (used in the rediect) to ignore it. According to the HTTP spec, you are doing the wrong thing by turning %2F in
I think the more correct thing to do would be to continue to clean the path but also mirror net/url's
|
|
Concerningly it looks like net/http.ServeMux suffers from the same issue - golang/go#14815 I'm not sure how anyone could consider a request to http://example.com/test/..%2Ffoobar to result in a HTTP 301 redirect to /foobar to be acceptable behaviour and not worthy of a breaking change to fix. |
I just ran into this. This bug can cause SSRF security vulnerabilities due to directory traversal in code relying on gorilla/mux and I'm extremely surprised it's been known about for so long (and incorrectly marked as closed) considering the severity. I'm all for soliciting patches from the community to fix issues, but leaving a security vulnerability open for years is extremely concerning. |
While SkipClean fixes the issue, it also completely bypasses the URL canonicalisation which may be undesirable. UseEncodedPath looks like a better option, although considering it opens the door for SSRF security vulnerabilities it arguably should be enabled by default (I'm not sure why unlike SkipClean it doesn't take a boolean though so once enabled it's not possible to disable the functionality). Unfortunately it looks like there's a bug when UseEncodedPath is enabled since it reads from url.EscapedPath(), but then writes back to url.Path which is then escaped. For example a request to It looks like the solution is to call url.ParseRequestURI() on the cleaned path, then write the returned url's Path and RawPath back to the copied req.URL. Setting UseEncodedPath to be enabled by default does not break any existing tests, nor does fixing the behaviour of UseEncodedPath to re-parse rather than writing to url.Path directly (although adding unit tests for the changed behaviours would be a good idea). Would there be interest in merging these changes so UseEncodedPath is default (adding a new func to be able to disable the now-default behaviour, along with a warning why that would likely be a bad idea), deprecating the existing UseEncodedPath func in favour of the new one, and fixing the double-escape problem described above, and adding appropriate unit tests for the changed behaviour? If so I'm more than happy to submit a PR in the coming days with those changes (or multiple PRs if preferred). |
MIGRATED - Refer to original discussion & golang bugs when reviewing
From mux created by cjellick: gorilla#354
What version of Go are you running? (Paste the output of
go version
)go version go1.10 linux/amd64
What version of gorilla/mux are you at? (Paste the output of
git rev-parse HEAD
inside$GOPATH/src/github.com/gorilla/mux
)07ba1fd
Describe your problem (and what you have tried so far)
The path cleaning performed in Router.ServerHTTP() works solely on request.URL.Path which decodes all characters. So characters, particularly slashes, that were escaped are unescaped in the redirect location sent back to the user as part of the 301 redirect.
Paste a minimal, runnable, reproduction of your issue below (use backticks to format it)
And then hit it with curl using a URL like this:
%2F is and escaped
/` and should not be interpreted as a path segment delimiter.In this case, the location of the redirect is
/anotherpath
but it should be/..%2Fanotherpath
The text was updated successfully, but these errors were encountered: