Skip to content

HttpHeaders cannot be mutated with firewalled requests from StrictServerWebExchangeFirewall #16034

Closed
@LeovR

Description

@LeovR

Describe the bug
Since spring-security 6.3.4 headers from firewalled requests from the new StrictServerWebExchangeFirewall, which was added here, cannot be mutated.

The reason is:
A call to mutate() on the exchange uses the DefaultServerHttpRequestBuilder which initializes the headers with a call to HttpHeaders.writableHttpHeaders(original.getHeaders()).
And in HttpHeaders.writableHttpHeaders new HttpHeaders are created if there are ReadOnlyHttpHeaders.
But the StrictServerWebExchangeFirewall wraps the original headers with the delegate class StrictFirewallHttpHeaders. Thus, those headers are not ReadOnlyHttpHeaders anymore.

To Reproduce
See sample below.

Expected behavior
The headers can be mutated, after calling mutate() even for firewalled requests.

Sample

Testcase:

package com.exmple.securityreadonlyheaders;

import org.junit.jupiter.api.Test;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.security.web.server.firewall.StrictServerWebExchangeFirewall;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

class SecurityReadonlyHeadersApplicationTests {
    @Test
    void firewalledExchange() {
        final var exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test").build());
        var firewall = new StrictServerWebExchangeFirewall();

        var firewalledExchange = firewall.getFirewalledExchange(exchange).block();
        assertDoesNotThrow(() -> firewalledExchange.mutate()
                .request(r -> r.headers(h -> h.set("Content-Type", "application/json"))));
    }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions