From 0f92415395c99ff2c7cb79896123356873c5046a Mon Sep 17 00:00:00 2001
From: Parikshit Dutta
Date: Sat, 2 May 2020 00:07:33 +0530
Subject: [PATCH] Fix non-standard HTTP method for CsrfWebFilter
Closes gh-8149
---
.../web/server/csrf/CsrfWebFilter.java | 5 +++--
.../web/server/csrf/CsrfWebFilterTests.java | 19 ++++++++++++++++++-
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/web/src/main/java/org/springframework/security/web/server/csrf/CsrfWebFilter.java b/web/src/main/java/org/springframework/security/web/server/csrf/CsrfWebFilter.java
index 33d06d39da..64dcc1b6af 100644
--- a/web/src/main/java/org/springframework/security/web/server/csrf/CsrfWebFilter.java
+++ b/web/src/main/java/org/springframework/security/web/server/csrf/CsrfWebFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,6 +60,7 @@ import static java.lang.Boolean.TRUE;
*
*
* @author Rob Winch
+ * @author Parikshit Dutta
* @since 5.0
*/
public class CsrfWebFilter implements WebFilter {
@@ -187,7 +188,7 @@ public class CsrfWebFilter implements WebFilter {
@Override
public Mono matches(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest())
- .map(r -> r.getMethod())
+ .flatMap(r -> Mono.justOrEmpty(r.getMethod()))
.filter(m -> ALLOWED_METHODS.contains(m))
.flatMap(m -> MatchResult.notMatch())
.switchIfEmpty(MatchResult.match());
diff --git a/web/src/test/java/org/springframework/security/web/server/csrf/CsrfWebFilterTests.java b/web/src/test/java/org/springframework/security/web/server/csrf/CsrfWebFilterTests.java
index cd3df76693..ad9ea7e89a 100644
--- a/web/src/test/java/org/springframework/security/web/server/csrf/CsrfWebFilterTests.java
+++ b/web/src/test/java/org/springframework/security/web/server/csrf/CsrfWebFilterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+
+import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
@@ -40,11 +42,14 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
import static org.springframework.mock.web.server.MockServerWebExchange.from;
import static org.springframework.web.reactive.function.BodyInserters.fromMultipartData;
/**
* @author Rob Winch
+ * @author Parikshit Dutta
* @since 5.0
*/
@RunWith(MockitoJUnitRunner.class)
@@ -183,6 +188,18 @@ public class CsrfWebFilterTests {
chainResult.assertWasSubscribed();
}
+ @Test
+ public void matchesRequireCSRFProtectionWhenNonStandardHTTPMethodIsUsed() {
+ final String NON_STANDARD_HTTP_METHOD = "non-standard-http-method";
+ MockServerWebExchange nonStandardHttpRequest = from(MockServerHttpRequest.method(HttpMethod.resolve(NON_STANDARD_HTTP_METHOD), "/"));
+
+ ServerWebExchangeMatcher serverWebExchangeMatcher = spy(CsrfWebFilter.DEFAULT_CSRF_MATCHER);
+ serverWebExchangeMatcher.matches(nonStandardHttpRequest);
+
+ verify(serverWebExchangeMatcher).matches(nonStandardHttpRequest);
+ assertThat(serverWebExchangeMatcher.matches(nonStandardHttpRequest).block().isMatch()).isTrue();
+ }
+
@Test
public void doFilterWhenSkipExchangeInvokedThenSkips() {
PublisherProbe chainResult = PublisherProbe.empty();