-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Prevent double decoding of % in url params #17997
Prevent double decoding of % in url params #17997
Conversation
Reviewers please check this PR with your own specific evil test cases. We will need to double check the redirects are correct too. |
This comment has been minimized.
This comment has been minimized.
Ah ok the problem is much more complicated... The issue is that chi has: // routeHTTP routes a http.Request through the Mux routing tree to serve
// the matching handler for a particular http method.
func (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) {
// Grab the route context object
rctx := r.Context().Value(RouteCtxKey).(*Context)
// The request routing path
routePath := rctx.RoutePath
if routePath == "" {
if r.URL.RawPath != "" {
routePath = r.URL.RawPath
} else {
routePath = r.URL.Path
}
if routePath == "" {
routePath = "/"
}
}
... The routePath should really use the |
There was an unfortunate regression in go-gitea#14293 which has led to the double decoding of url parameter elements if they contain a '%'. This is due to an issue with the way chi decodes its RoutePath. In detail the problem lies in mux.go where the routeHTTP path uses the URL.RawPath or even the URL.Path instead of the escaped path to do routing. This PR simply forcibly sets the routePath to that of the EscapedPath. Fix go-gitea#17938 Signed-off-by: Andrew Thornton <art27@cantab.net>
600e9c3
to
4298560
Compare
Are you sure we are not using chi in the wrong way? It looks like a workaround now. |
If you don't use the escapedpath you use partially decoded URLs for routing and get partially decoded results assigned to ctx.Params. (partially decoded in that you can't safely decode or just use them as is because some things have been decoded and somethings haven't. The result is that %25 will often be predecoded to % but other things won't be - and because you don't have the original URL (except as the full RequestURI) you don't really know how to interpret a % encoded string. The only consistent (and safe) thing to do is to use the encoded URL for routing. Feel free to play around with it though. Here are few (unencoded) filenames you might want to try to make it possible to route to:
|
Nice catch. Should we add some documents and unit tests to describe the expected behavior? And I am not sure how most reverse proxies process these encoded URLs (what will be passed to backend)
|
Isn't this an upstream problem? |
Signed-off-by: Andrew Thornton <art27@cantab.net>
Not sure if it's definitely an upstream problem - this may be by design. Partial decoding of the urls may or may not be nice depending on your application - in our case it's bad because we're rendering urls that we have little to no control over so we have to have a simple mapping. Other users may not mind that if you want to have a % in your url it needs to be double escaped. The solution proposed here is to use the mechanisms already available to us as provided by chi to tell it to use the EscapedPath instead of the partially escaped one. |
I've added unit tests. I'm not sure what kind of document would be beneficial - this PR is simply making sure that ctx.Params() always gives you the non-url encoded parameter from the url.
That's a configuration issue. The reverse proxy should be passing the escaped url correctly - if it's de-escaping things then that's incorrect configuration.
It's simple: a file that is named
a file that is named
a file that is named |
@zeripath I didn't say clearly. Let's see an example: For a simple Go http server:
nginx config:
We see different behaviors: Reference: https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy That's what I mean about document. Current Gitea document for nginx (with sub-path) will cause such double-decoding. Users should tune their reverse proxy carefully. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ the tests
@wxiaoguang this partial decoding of URI paths containing %2f is not an actual problem. It would only be a problem if filenames were allowed to contain / in them (which they're not - even on Windows) - and we don't use the URI but the escaped URL which is the same in both of these cases. (IIRC URLs aren't actually allowed %2f in path components.) It would be a problem if %252f in an URI became %2f in an URL because then that would map to looking at a file with '/' in its name and prevent looking at files with %2f in their names. |
There was an unfortunate regression in go-gitea#14293 which has led to the double decoding of url parameter elements if they contain a '%'. This is due to an issue with the way chi decodes its RoutePath. In detail the problem lies in mux.go where the routeHTTP path uses the URL.RawPath or even the URL.Path instead of the escaped path to do routing. This PR simply forcibly sets the routePath to that of the EscapedPath. Fix go-gitea#17938 Signed-off-by: Andrew Thornton <art27@cantab.net>
## [1.15.8](https://github.com/go-gitea/gitea/releases/tag/v1.15.8) - 2021-12-19 * BUGFIXES * Reset locale on login (go-gitea#18023) (go-gitea#18025) * Fix reset password email template (go-gitea#17025) (go-gitea#18022) * Fix outType on gitea dump (go-gitea#18000) (go-gitea#18016) * Ensure complexity, minlength and isPwned are checked on password setting (go-gitea#18005) (go-gitea#18015) * Fix rename notification bug (go-gitea#18011) * Prevent double decoding of % in url params (go-gitea#17997) (go-gitea#18001) * Prevent hang in git cat-file if the repository is not a valid repository (Partial go-gitea#17991) (go-gitea#17992) * Prevent deadlock in create issue (go-gitea#17970) (go-gitea#17982) * TESTING * Use non-expiring key. (go-gitea#17984) (go-gitea#17985) Signed-off-by: Andrew Thornton <art27@cantab.net>
## [1.15.8](https://github.com/go-gitea/gitea/releases/tag/v1.15.8) - 2021-12-19 * BUGFIXES * Reset locale on login (#18023) (#18025) * Fix reset password email template (#17025) (#18022) * Fix outType on gitea dump (#18000) (#18016) * Ensure complexity, minlength and isPwned are checked on password setting (#18005) (#18015) * Fix rename notification bug (#18011) * Prevent double decoding of % in url params (#17997) (#18001) * Prevent hang in git cat-file if the repository is not a valid repository (Partial #17991) (#17992) * Prevent deadlock in create issue (#17970) (#17982) * TESTING * Use non-expiring key. (#17984) (#17985) Signed-off-by: Andrew Thornton <art27@cantab.net> * Update CHANGELOG.md Co-authored-by: 6543 <6543@obermui.de>
PR go-gitea#17997 means that urls with terminal '/' are no longer immediately mapped to the url without a terminal slash. However, it has revealed that the NotFound handler appears to have been lost. This PR adds back in a NotFound handler that simply redirects to a path without the terminal slash or runs the NotFound handler. Fix go-gitea#18060 Signed-off-by: Andrew Thornton <art27@cantab.net>
PR #17997 means that urls with terminal '/' are no longer immediately mapped to the url without a terminal slash. However, it has revealed that the NotFound handler appears to have been lost. This PR adds back in a NotFound handler that simply redirects to a path without the terminal slash or runs the NotFound handler. Fix #18060 Signed-off-by: Andrew Thornton <art27@cantab.net>
Backport go-gitea#18062 PR go-gitea#17997 means that urls with terminal '/' are no longer immediately mapped to the url without a terminal slash. However, it has revealed that the NotFound handler appears to have been lost. This PR adds back in a NotFound handler that simply redirects to a path without the terminal slash or runs the NotFound handler. Fix go-gitea#18060 Signed-off-by: Andrew Thornton <art27@cantab.net>
Backport #18062 PR #17997 means that urls with terminal '/' are no longer immediately mapped to the url without a terminal slash. However, it has revealed that the NotFound handler appears to have been lost. This PR adds back in a NotFound handler that simply redirects to a path without the terminal slash or runs the NotFound handler. Fix #18060 Signed-off-by: Andrew Thornton <art27@cantab.net>
A consequence of forcibly setting the RoutePath to the escaped url is that the auto routing to endpoints without terminal slashes fails (Causing go-gitea#18060.) This failure raises the possibility that forcibly setting the RoutePath causes other unexpected behaviours too. Therefore, instead we should simply pre-escape the URL in the process registering handler. Then the request URL will be properly escaped for all the following calls. Fix go-gitea#17938 Fix go-gitea#18060 Replace go-gitea#18062 Replace go-gitea#17997 Signed-off-by: Andrew Thornton <art27@cantab.net>
A consequence of forcibly setting the RoutePath to the escaped url is that the auto routing to endpoints without terminal slashes fails (Causing #18060.) This failure raises the possibility that forcibly setting the RoutePath causes other unexpected behaviors too. Therefore, instead we should simply pre-escape the URL in the process registering handler. Then the request URL will be properly escaped for all the following calls. Fix #17938 Fix #18060 Replace #18062 Replace #17997 Signed-off-by: Andrew Thornton <art27@cantab.net>
…ea#18086) Backport go-gitea#18086 A consequence of forcibly setting the RoutePath to the escaped url is that the auto routing to endpoints without terminal slashes fails (Causing go-gitea#18060.) This failure raises the possibility that forcibly setting the RoutePath causes other unexpected behaviors too. Therefore, instead we should simply pre-escape the URL in the process registering handler. Then the request URL will be properly escaped for all the following calls. Fix go-gitea#17938 Fix go-gitea#18060 Replace go-gitea#18062 Replace go-gitea#17997 Signed-off-by: Andrew Thornton <art27@cantab.net>
#18098) Backport #18086 A consequence of forcibly setting the RoutePath to the escaped url is that the auto routing to endpoints without terminal slashes fails (Causing #18060.) This failure raises the possibility that forcibly setting the RoutePath causes other unexpected behaviors too. Therefore, instead we should simply pre-escape the URL in the process registering handler. Then the request URL will be properly escaped for all the following calls. Fix #17938 Fix #18060 Replace #18062 Replace #17997 Signed-off-by: Andrew Thornton <art27@cantab.net>
There was an unfortunate regression in go-gitea#14293 which has led to the double decoding of url parameter elements if they contain a '%'. This is due to an issue with the way chi decodes its RoutePath. In detail the problem lies in mux.go where the routeHTTP path uses the URL.RawPath or even the URL.Path instead of the escaped path to do routing. This PR simply forcibly sets the routePath to that of the EscapedPath. Fix go-gitea#17938 Signed-off-by: Andrew Thornton <art27@cantab.net>
PR go-gitea#17997 means that urls with terminal '/' are no longer immediately mapped to the url without a terminal slash. However, it has revealed that the NotFound handler appears to have been lost. This PR adds back in a NotFound handler that simply redirects to a path without the terminal slash or runs the NotFound handler. Fix go-gitea#18060 Signed-off-by: Andrew Thornton <art27@cantab.net>
…ea#18086) A consequence of forcibly setting the RoutePath to the escaped url is that the auto routing to endpoints without terminal slashes fails (Causing go-gitea#18060.) This failure raises the possibility that forcibly setting the RoutePath causes other unexpected behaviors too. Therefore, instead we should simply pre-escape the URL in the process registering handler. Then the request URL will be properly escaped for all the following calls. Fix go-gitea#17938 Fix go-gitea#18060 Replace go-gitea#18062 Replace go-gitea#17997 Signed-off-by: Andrew Thornton <art27@cantab.net>
There was an unfortunate regression in #14293 which has led to the double decoding
of url parameter elements if they contain a '%'. This is due to an issue
with the way chi decodes its RoutePath. In detail the problem lies in
mux.go where the routeHTTP path uses the URL.RawPath or even the
URL.Path instead of the escaped path to do routing.
This PR simply forcibly sets the routePath to that of the EscapedPath.
Fix #17938
Although this fixes a bug - users may have worked around this bug by creating links that would make this work - especially in the wiki. As users may need to be aware of this I am marking this PR as breaking in order to highlight this issue.
Signed-off-by: Andrew Thornton art27@cantab.net