From 12bd55af5dd50cf6122de0d22660e0e137c29f7c Mon Sep 17 00:00:00 2001
From: caodongxia <315816521@qq.com>
Date: Thu, 17 Dec 2020 17:22:31 +0800
Subject: [PATCH] fix cve-2020-5421
Reference: https://github.com/spring-projects/spring-framework/commit/2f75212eb667a30fe2fa9b5aca8f22d5e255821f

---
 .../springframework/web/util/UrlPathHelper.java    | 12 +-----------
 .../org/springframework/web/util/WebUtils.java     |  3 +++
 .../web/util/UrlPathHelperTests.java               | 14 +++-----------
 .../springframework/web/util/WebUtilsTests.java    | 10 ++++++++++
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
index 3307698..bda7f9c 100644
--- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
+++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
@@ -453,7 +453,7 @@ public class UrlPathHelper {
 	 */
 	public String removeSemicolonContent(String requestUri) {
 		return (this.removeSemicolonContent ?
-				removeSemicolonContentInternal(requestUri) : removeJsessionid(requestUri));
+				removeSemicolonContentInternal(requestUri) : requestUri);
 	}
 
 	private String removeSemicolonContentInternal(String requestUri) {
@@ -467,16 +467,6 @@ public class UrlPathHelper {
 		return requestUri;
 	}
 
-	private String removeJsessionid(String requestUri) {
-		int startIndex = requestUri.toLowerCase().indexOf(";jsessionid=");
-		if (startIndex != -1) {
-			int endIndex = requestUri.indexOf(';', startIndex + 12);
-			String start = requestUri.substring(0, startIndex);
-			requestUri = (endIndex != -1) ? start + requestUri.substring(endIndex) : start;
-		}
-		return requestUri;
-	}
-
 	/**
 	 * Decode the given URI path variables via
 	 * {@link #decodeRequestString(HttpServletRequest, String)} unless
diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
index 7bf5fd2..cfbf0d2 100644
--- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
+++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
@@ -749,6 +749,9 @@ public abstract class WebUtils {
 			int index = pair.indexOf('=');
 			if (index != -1) {
 				String name = pair.substring(0, index);
+				if (name.equalsIgnoreCase("jsessionid")) {
+				continue;
+				}
 				String rawValue = pair.substring(index + 1);
 				for (String value : StringUtils.commaDelimitedListToStringArray(rawValue)) {
 					result.add(name, value);
diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
index 1f59dcd..51fc224 100644
--- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
@@ -112,22 +112,14 @@ public class UrlPathHelperTests {
 	}
 
 	@Test
-	public void getRequestKeepSemicolonContent() throws UnsupportedEncodingException {
+	public void getRequestKeepSemicolonContent() {
 		helper.setRemoveSemicolonContent(false);
 
 		request.setRequestURI("/foo;a=b;c=d");
 		assertEquals("/foo;a=b;c=d", helper.getRequestUri(request));
 
 		request.setRequestURI("/foo;jsessionid=c0o7fszeb1");
-		assertEquals("jsessionid should always be removed", "/foo", helper.getRequestUri(request));
-
-		request.setRequestURI("/foo;a=b;jsessionid=c0o7fszeb1;c=d");
-		assertEquals("jsessionid should always be removed", "/foo;a=b;c=d", helper.getRequestUri(request));
-
-		// SPR-10398
-
-		request.setRequestURI("/foo;a=b;JSESSIONID=c0o7fszeb1;c=d");
-		assertEquals("JSESSIONID should always be removed", "/foo;a=b;c=d", helper.getRequestUri(request));
+		assertEquals("/foo;jsessionid=c0o7fszeb1", helper.getRequestUri(request));
 	}
 
 	@Test
@@ -384,4 +376,4 @@ public class UrlPathHelperTests {
 		assertNull(this.helper.getOriginatingQueryString(request));
 	}
 
-}
\ No newline at end of file
+}
diff --git a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
index f6edf65..57ec975 100644
--- a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
@@ -103,6 +103,16 @@ public class WebUtilsTests {
 		variables = WebUtils.parseMatrixVariables("colors=red;colors=blue;colors=green");
 		assertEquals(1, variables.size());
 		assertEquals(Arrays.asList("red", "blue", "green"), variables.get("colors"));
+		variables = WebUtils.parseMatrixVariables("jsessionid=c0o7fszeb1");
+		assertTrue(variables.isEmpty());
+		variables = WebUtils.parseMatrixVariables("a=b;jsessionid=c0o7fszeb1;c=d");
+		assertEquals(2, variables.size());
+		assertEquals(Collections.singletonList("b"), variables.get("a"));
+		assertEquals(Collections.singletonList("d"), variables.get("c"));
+		variables = WebUtils.parseMatrixVariables("a=b;jsessionid=c0o7fszeb1;c=d");
+		assertEquals(2, variables.size());
+		assertEquals(Collections.singletonList("b"), variables.get("a"));
+		assertEquals(Collections.singletonList("d"), variables.get("c"));
 	}
 
 }
-- 
2.27.0

