Skip to content

StrictFirewallServerWebExchange should still protect when request is mutated #16978

Closed
@siddhivinayak-sk

Description

@siddhivinayak-sk

Describe the bug

With Spring Boot 3.3.4 and Spring Cloud 2024.0.1 along with spring-security-web dependency, inside implementation of custom WebFilter, the exchange object provided of StrictFirewallServerWebExchange type.

This class StrictFirewallServerWebExchange is defined at org.springframework.security.web.server.firewall.StrictServerWebExchangeFirewall and it has private implementation of decorators and builds for ServerWebExchange and ServerHttpRequest.

It is supposed to provide mutation on request object by using method like:

        val buildRequest = request
                .mutate()
                .header("xyz", "abc")
                .build()

Expected behavior is after mutation it should return instance of StrictFirewallHttpRequest but it returns org.springframework.http.server.reactive.DefaultServerHttpRequestBuilder$MutatedServerHttpRequest.

This creates issue whenever request is modified using WebFilter, there is no impact of changes.

To Reproduce

  1. Create a sample reactive spring boot application with spring security, Http firewall
  2. Add a pre WebFilter
  3. Try to mutate exchange like this:
        var buildRequest = exchange.request
                .mutate()
                .header("xyz", "abc")
                .build()
        var buildExchange = exchange.mutate().request(buildRequest).build()
    
  4. Either check returned buildExchange type or do the chain.filter(buildExchange) and see the endpoint result.

Expected behavior

If we do mutation like (without adding header), it results correct instance:

        var buildRequest = exchange.request
                .mutate()
                .build()

Image

Similarly, when we modify request and a header like:
var buildRequest = exchange.request .mutate() .header("xyz", "abc") .build() var buildExchange = exchange.mutate().request(buildRequest).build()

It should also return correct instance (of StrictFirewallHttpRequest) but it returns:

Image

While investigation, found that StrictFirewallBuilder.header(String headerName, String... headerValues) method calls same method on delegated object which returns DefaultServerHttpRequestBuilder type while ideally this method should wrap into StrictFirewallBuilder type:

                public ServerHttpRequest.Builder header(String headerName, String... headerValues) {
                    return this.delegate.header(headerName, headerValues);
                }

Metadata

Metadata

Assignees

Labels

in: webAn issue in web modules (web, webmvc)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions