Netflix / zuul

Zuul is a gateway service that provides dynamic routing, monitoring, resiliency, security, and more.
Apache License 2.0
13.43k stars 2.37k forks source link

Netflix Zuul query string encoding #215

Open anoll opened 8 years ago

anoll commented 8 years ago

This is a copy of the stackoverflow issue: http://stackoverflow.com/questions/36475845/netflix-zuul-query-string-encoding

When sending a request via Zuul to a client, Zuul seems to change the query String. More specifically, if the client should receive an url-encoded query String, Zuul decodes the query String once. Here is a concrete example:

If "http://localhost:8080/demo/demo?a=http%3A%2F%2Fsomething/" is sent to the client, the client receives as a query String "a=http://something/".

Looking into Zuul`s code, the function "buildZuulRequestQueryParams" uses "HTTPRequestUtils.getInstance().getQueryParams();" which decodes the query String.

Is this a desired feature or a bug?

ausmith commented 8 years ago

The implementation of zuul that my group is using had instances where bad query params were sent to it, causing the entire application to error out. https://github.com/Netflix/zuul/pull/161 added the query param decoding, https://github.com/Netflix/zuul/pull/198 handles a bug we found where encoded ampersands were not getting re-encoded, and https://github.com/Netflix/zuul/pull/199 handles cases where query params are missing an =.

Hope that answers the "why" for you. As these were merged in, I believe that it is a desired feature.

anoll commented 8 years ago

Thanks for the detailed response.

In our case, the client assumes the query string to be encoded in a certain way. Is there a way to configure the behavior of Zuul such that Zuul does not modify the query string? That would be a desired feature for us :-)

ausmith commented 8 years ago

@anoll the changes I described were all in the zuul-simple-webapp present in the zuul project, so your custom implementation likely inherited this. If you go into your application's SimpleHostRoutingFilter.groovy you should be able to make these modifications yourself. The appropriate function to make your changes to is getQueryString().

hohwille commented 7 years ago

Zuul simply does too much auto-magic here and therefore some apps stop working if they are operated behind zuul as reverse proxy. An example is e.g. foswiki that uses semicolon instead of ampersand as separator for query parameters. See also here for discussions on that but however, the w3c standard seems to allow this: https://stackoverflow.com/questions/3481664/semicolon-as-url-query-separator However, zuul does not allow this: https://github.com/Netflix/zuul/blob/c87e0c2a6b65a19ca8eb493d281ee812f7b60794/zuul-core/src/main/java/com/netflix/zuul/util/HTTPRequestUtils.java#L166

Ampersand as separator is considered as fixed separator char and semicolon is not honored. Hence everything behind the first equals sign is considered as value. Therefore subsequent equals signs are falsely escaped to %3D resulting in an invalid URL. An actual URL of a foswiki registration link send via Email looks as following: http://zuul.mydomain.org/foswiki/bin/register?action=approve;code=MyLogin.9285561;referee=AdminUser I can neither configure foswiki to use ampersand instead of semicolon nor I can make zuul pass these requests properly to the physical wiki server without breaking the request URL.

Conclusion: IMHO zuul is buggy here and needs to be fixed.

haagrawa commented 6 years ago

Just add following in application.yml file zuul : forceOriginalQueryStringEncoding: true

This will internally encode again your query param. You can also refer method buildHttpRequest() of class SimpleHostRoutingFilter

sandy-adi commented 5 years ago

Just add following in application.yml file zuul : forceOriginalQueryStringEncoding: true

This will internally encode again your query param. You can also refer method buildHttpRequest() of class SimpleHostRoutingFilter

This solution is specific to Spring Gateway.

I think manipulating the URI in transit is definitely not a good idea. The request URI should be considered immutable. @artgon could you please check ProxyEndPoint#L962 and explain the reason behind decoding the query string?

artgon commented 5 years ago

That's a good question, I believe it's to sanitize the query params but it may be worth adding a flag similar to what Spring did.

sandy-adi commented 5 years ago

That's a good question, I believe it's to sanitize the query params but it may be worth adding a flag similar to what Spring did.

@artgon I took a crack at this, could you please take a look?

feature: Control request parameter encoding with configuration

sandy-adi commented 5 years ago

Addressed in PR #563