Skip to content

HttpHeaders cannot be mutated with firewalled requests from StrictServerWebExchangeFirewall #16034

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

Closed
LeovR opened this issue Nov 4, 2024 · 1 comment
Assignees
Labels
status: duplicate A duplicate of another issue type: bug A general bug

Comments

@LeovR
Copy link
Contributor

LeovR commented Nov 4, 2024

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"))));
    }
}
@LeovR LeovR added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 4, 2024
@rwinch
Copy link
Member

rwinch commented Nov 4, 2024

Thanks for the report @LeovR this is a duplicate of #15989 ( workaround on it) which is superseded by spring-projects/spring-framework#33789

@rwinch rwinch closed this as completed Nov 4, 2024
@rwinch rwinch self-assigned this Nov 4, 2024
@rwinch rwinch added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants