Skip to content
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

Encoded slash in path variable causes error 400 in WebFlux - regression in Spring Boot 3.3.5 #42907

Closed
kdebski85 opened this issue Oct 28, 2024 · 4 comments
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid

Comments

@kdebski85
Copy link

I develop a Spring WebFlux application with Netty.
After upgrade of Spring Boot from 3.3.4 to 3.3.5, http status 400 is returned when a path contains encoded slash.
The encoded slash is a part of path variable.

For example, the following endpoint returns status 400 for GET /api/a%2Fb/foo in 3.3.5.

    @GetMapping(path = "/api/{param}/foo", produces = APPLICATION_JSON_VALUE)
    public Mono<String> foo(@PathVariable String param) {
        return Mono.just(param);
    }

In 3.3.4, exactly same request returned 200 with a/b in the response.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 28, 2024
@bclozel
Copy link
Member

bclozel commented Oct 28, 2024

I assume there is something else going on.
I cannot reproduce this behavior.

import reactor.core.publisher.Mono;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	@GetMapping(path = "/api/{param}/foo", produces = MediaType.TEXT_PLAIN_VALUE)
	public Mono<String> foo(@PathVariable String param) {

		return Mono.just(param);
	}
}
curl -v http://localhost:8080/api/a%2Fb/foo
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /api/a%2Fb/foo HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 3
<
* Connection #0 to host localhost left intact
a/b%      

Maybe your application has Spring Security configured?
In this case, this is probably due to the recent introduction of ServerWebExchangeFirewall, see spring-projects/spring-security#15991. In this case, the reference documentation might help you with this or you can reach out to the Spring Security team.

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Oct 28, 2024
@bclozel bclozel added status: invalid An issue that we don't feel is valid for: external-project For an external project and not something we can fix and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 28, 2024
@kdebski85
Copy link
Author

I debugged that the issue is caused by org.springframework.security.web.server.firewall.StrictServerWebExchangeFirewall and downgrading to org.springframework.security:spring-security-web:6.3.3 resolves it.

I found that there is a method
https://docs.spring.io/spring-security/reference/6.4-SNAPSHOT/api/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.html#setAllowUrlEncodedSlash(boolean)

Why such breaking change was introduced in a hotfix version?
How to configure StrictServerWebExchangeFirewall in Spring Boot?

@bclozel
Copy link
Member

bclozel commented Oct 28, 2024

Why such breaking change was introduced in a hotfix version?
How to configure StrictServerWebExchangeFirewall in Spring Boot?

I guess those are questions for the Spring Security team. Maybe ask this question on StackOverflow?
Have you tried contributing your own StrictServerWebExchangeFirewall bean to the application context?

@kdebski85
Copy link
Author

I tried my custom StrictServerWebExchangeFirewall, but it was unused.

The issue was that setting the firewall was added after the release:
spring-projects/spring-security@3ba1263

For a time being, I will use BeanPostProcessor approach mentioned at:
spring-projects/spring-security#15974

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants