-
Notifications
You must be signed in to change notification settings - Fork 472
LinkBuilderSupport.toUri()
double-encodes request parameters
#1722
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
Comments
It's likely to be #1583, which implements encoding according to the rules defined in RFC 6570. That lists the equals sign (
I read this as: as |
We're using the resulting URL to perform a query with |
@jochenberger We are struggling with the same problem. Yes, MockMvc performs an additional encoding on URIs. So, if you are directly taking an href from a HATEOAS link that contains an encoded char it will perform a double encoding. Variable value is in the format WebMvcLinkBuilder in Spring HATEOAS 1.3.x created an URI WebMvcLinkBuilder in Spring HATEOAS 1.4.x creates now URI A workaround is to We are still in the analysis if this new behavior breaks other clients on our side, e.g. calls done by RestTemplate with variable expansion. or our Angular/React single page applications. I think the root cause can be found in the implementation of the encoding of the `TemplateVariables, see: public String encode(String value) {
switch (this) {
case DOT:
case SEGMENT:
case PATH_SEGMENT:
case PATH_STYLE_PARAMETER:
case REQUEST_PARAM:
case REQUEST_PARAM_CONTINUED:
case SIMPLE:
return UriUtils.encode(value, StandardCharsets.UTF_8);
case FRAGMENT:
default:
return UriUtils.encodePath(value, StandardCharsets.UTF_8);
}
} The different variable types are encoded either by
|
That's useful feedback, thank you. One thing you have to be careful about is to note that I'll take this back to the Spring team and see what they think. |
@odrotbohm Thx for your insights. The RFC for UriTemplates is really odd as it does not seems to reflect any context information regarding the URI component the variable is used in. Always only allowing the "unreserved characters" independent of the URI component seems to be quite restrictive to build URIs via templates. Nevertheless the encoded URI are valid URIs and would work wenn used in a browser or other clients but in combination with Spring MVC test framework (aka MockMvc) we now have a problem as links extracted from HAL resources can no longer directly be used in MockMvc if a reserved character with would be valid for a path is used for a variable value. Should I create a simple demonstration project / test case for this behaviour? |
Anything small that helps us see the problem is appreciated. |
Simple test project to clarify the unexpected / changed behavior: Using Spring Boot 2.5.x with Spring HATEOAS 1.3.x all test will be successful. |
I have extended the sample project to show case that it might also break Spring |
After some further tests I need some clarification how HAL/HATEOAS links schould be handled by a client as this problem also occurs with URLs containing request parameters that contain character like a space
So my question is: I also checked the |
Some further insights: the documentation of Spring is not very consistent in regard of the various REST clients and the behaviour of URI- The documentation of
So no confusion here. It should be clear that you should use The documentation of So it seems to me, that Spring HATEOAS does not have a bug, but the usage patterns in combination with the different Spring.-based clients might need better, more consistent documentation with examples. |
I am not sure this is fully related, but I created a repo with a very very basic test and it seems there is indeed some issue in spring hateoas: https://github.com/ThanksForAllTheFish/doubleencoding/blob/main/src/test/kotlin/com/t4atf/doubleencoding/DoubleEncodingTest.kt
fails with
The issue is the the backing uri components has its @odrotbohm @dpasek-senacor (please apologies if it was not ok to tag you) |
Thanks for the sample, but I'm not gonna debug a project written in Kotlin if the issue to be discussed does not involve Kotlin in the first place. Please avoid anything that distracts from the actual problem to investigate. |
I converted the project to java, relevant test is https://github.com/ThanksForAllTheFish/doubleencoding/blob/java/src/test/java/com/t4atf/doubleencoding/DoubleEncodingTest.java Again,
|
Thanks! I'll have a look ASAP. |
There's a mismatch in the way the underlying |
Are you saying I am using Sorry if this is a dumb question, but in my eyes the value used is not encoded ( I am not sure about https://github.com/spring-projects/spring-hateoas/blob/main/src/main/java/org/springframework/hateoas/server/core/WebHandler.java#L166, because the query parameter at that point is encoded, but Again, sorry for babbling, I have a small example here, but I am sure that on a larger scale there are more considerations in place that I am not seeing |
You're essentially right, but we're running into an (apparent) limitation of I'll push a fix in a minute that basically has the gist of it in its commit message, too. |
LinkBuilderSupport.toUri()
double-encodes request parameters
…rt.toUri(…). We unfortunately cannot use UriComponentsBuilder in a way that we can populate it with encoded parameters *and* expand encoded path variable values. We currently use ….buildAndExpand(…) which considers the values provided unencoded but we never actually call ….toUri() on the resulting UriComponents instance. We unfortunately cannot fix the problem at its root, as the only alternative would be to call ….build(true) indicating values already encoded but that stumbles above the template variables still present in the original template. The only workaround right now is never calling UriComponents.toUri() but ….toUriString() as that doesn't apply the pending encoding that's not actually needed as we start with fully encoded values in the first place.
That's in place now. Fixed for 2.0, 1.5 and 1.4. Feel free to give the snapshots a try. |
Do you know when this will be available in a release? We need that fix for our project. |
A footnote for anyone arriving here is to watch out for passing It is also possible to configure the restTemplate to only encode values via |
We're experiencing a change in behavior regarding path variable expansion.
Consider the following Java code and output:
Output:
In 1.4.0, the "=" is encoded as "%3D", in 1.3.x, it wasn't. This causes issues with Spring Security because a request to the resulting URL is rejected with
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String "%25"
.This is probably related to db1cd5d (#1485).
Are we doing something wrong?
The text was updated successfully, but these errors were encountered: