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

Fix non-standard HTTP method for CsrfWebFilter #8452

Closed

Conversation

parikshitdutta
Copy link
Contributor

@parikshitdutta parikshitdutta commented May 1, 2020

Fixed NPE for HTTP requests with non-standard HTTP method in CsrfWebFilter

  1. CsrfWebFilter code updated to deal with null value while non-standard HTTP methods used
  2. Respective test added to validate the scenario with non-standard (custom) HTTP method

Expected Result:
Non-standard HTTP methods should match for CsrfProtection Requirement now, instead of throwing NPE and resulting HTTP 5xx

Fixes gh-8149

Copy link
Member

@rwinch rwinch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @parikshitdutta! I've added some feedback inline

@@ -187,7 +187,7 @@ public static void skipExchange(ServerWebExchange exchange) {
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest())
.map(r -> r.getMethod())
.map(r -> (r.getMethod() != null ? r.getMethod() : Mono.empty()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me. You shouldn't map to a publisher. It should be a .flatMap and both code paths need to be a Publisher

Suggested change
.map(r -> (r.getMethod() != null ? r.getMethod() : Mono.empty()))
.flatMap(r -> Mono.justOrEmpty(r.getMethod()))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to understand the required change, my understanding was the return from "getMethod" in question is time bounded, not a value for future, therefore it would be okay to use condition in map.

Please enlighten me if I am missing something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that if r.getMethod() is null then, it is a .map(Mono.empty()) means that it is now a Mono<Mono<Empty>>. Instead you want just Mono.empty().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally make sense! thanks for clarifying.

@@ -284,4 +305,12 @@ String ok() {
return "ok";
}
}

static class MockNonStandardHttpRequest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a need to externalize this or could you just directly use MockServerHttpRequest.method directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to build MockServerWebExchange from NonStandard HTTP Request (i.e: "PURGE", "REVOKE" etc.), by using user defined string which is not a valid HTTP Method.

Now mocking without externalizing meaning I have to use get, post or other defined builders in MockServerHttpRequest (MockServerHttpRequest itself not extensible) or even if I try to do in different way, most likely i would end up writing redundant code.

Please share your thought.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it is only being used once, so I think it can safely be consolidated without having redundant code.

public void filterWhenNonStandardHTTPMethodUsedThenMatchesRequireCSRFProtection() {
MockServerWebExchange nonStandardHttpRequest = from(MockNonStandardHttpRequest.nonStandardHTTPMethod("/"));

ServerWebExchangeMatcher serverWebExchangeMatcher = spy(CsrfWebFilter.DEFAULT_CSRF_MATCHER);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to test the CsrfWebFilter and the matcher here. I think we can just check CsrfWebFilter.DEFAULT_CSRF_MATCHER directly. If we need to test both, we should probably create separate tests.

@parikshitdutta
Copy link
Contributor Author

Hi @rwinch, Please review the changes as you find time, I will look forward to your feedback.

@eleftherias eleftherias removed their assignment May 7, 2020
@rwinch rwinch closed this in 8d44763 May 11, 2020
@rwinch rwinch changed the title Fixed NPE for HTTP requests with non-standard HTTP method for CsrfWebFilter Fix non-standard HTTP method for CsrfWebFilter May 11, 2020
@rwinch rwinch added in: web An issue in web modules (web, webmvc) type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels May 11, 2020
@rwinch rwinch self-assigned this May 11, 2020
@rwinch rwinch added this to the 5.4.0-M2 milestone May 11, 2020
rwinch added a commit that referenced this pull request May 12, 2020
@spring-projects-issues spring-projects-issues added the status: backported An issue that has been backported to maintenance branches label May 12, 2020
rwinch added a commit that referenced this pull request May 12, 2020
rwinch added a commit that referenced this pull request May 12, 2020
rwinch added a commit that referenced this pull request May 12, 2020
@rwinch
Copy link
Member

rwinch commented May 12, 2020

Thanks for the Pull Request! This is now merged into master 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix non-standard HTTP method for CsrfWebFilter
4 participants