Security context
MediumGHSA-rhcg-rwhx-qj3j CVE-2014-3578CWE-22Published May 14, 2022

Improper Limitation of a Pathname to a Restricted Directory in Spring Framework

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

3.0.0 → fixed in 3.2.94.0.0 → fixed in 4.0.5

Details

Directory traversal vulnerability in Pivotal Spring Framework 3.x before 3.2.9 and 4.0 before 4.0.5 allows remote attackers to read arbitrary files via a crafted URL.

The fix

Improve StringUtils.cleanPath

Rossen Stoyanchev· May 15, 2014, 09:26 PM+81748167bfa3
spring-core/src/main/java/org/springframework/util/StringUtils.java+6 1
@@ -622,7 +622,12 @@ public static String cleanPath(String path) {
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
- pathToUse = pathToUse.substring(prefixIndex + 1);
+ if (prefix.contains("/")) {
+ prefix = "";
+ }
+ else {
+ pathToUse = pathToUse.substring(prefixIndex + 1);
+ }
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
spring-core/src/test/java/org/springframework/util/StringUtilsTests.java+2 0
@@ -299,6 +299,8 @@ public void testCleanPath() {
assertEquals("../mypath/myfile", StringUtils.cleanPath("../mypath/../mypath/myfile"));
assertEquals("../mypath/myfile", StringUtils.cleanPath("mypath/../../mypath/myfile"));
assertEquals("/../mypath/myfile", StringUtils.cleanPath("/../mypath/myfile"));
+ assertEquals("/mypath/myfile", StringUtils.cleanPath("/a/:b/../../mypath/myfile"));
+ assertEquals("file:///c:/path/to/the%20file.txt", StringUtils.cleanPath("file:///c:/some/../path/to/the%20file.txt"));
}
public void testPathEquals() {

Improve StringUtils.cleanPath

Rossen Stoyanchev· May 15, 2014, 09:26 PM+818ee4651038
spring-core/src/main/java/org/springframework/util/StringUtils.java+6 1
@@ -622,7 +622,12 @@ public static String cleanPath(String path) {
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
- pathToUse = pathToUse.substring(prefixIndex + 1);
+ if (prefix.contains("/")) {
+ prefix = "";
+ }
+ else {
+ pathToUse = pathToUse.substring(prefixIndex + 1);
+ }
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
spring-core/src/test/java/org/springframework/util/StringUtilsTests.java+2 0
@@ -299,6 +299,8 @@ public void testCleanPath() {
assertEquals("../mypath/myfile", StringUtils.cleanPath("../mypath/../mypath/myfile"));
assertEquals("../mypath/myfile", StringUtils.cleanPath("mypath/../../mypath/myfile"));
assertEquals("/../mypath/myfile", StringUtils.cleanPath("/../mypath/myfile"));
+ assertEquals("/mypath/myfile", StringUtils.cleanPath("/a/:b/../../mypath/myfile"));
+ assertEquals("file:///c:/path/to/the%20file.txt", StringUtils.cleanPath("file:///c:/some/../path/to/the%20file.txt"));
}
public void testPathEquals() {

Improve StringUtils.cleanPath

Rossen Stoyanchev· May 15, 2014, 09:26 PM+81f6fddeb6eb
spring-core/src/main/java/org/springframework/util/StringUtils.java+6 1
@@ -621,7 +621,12 @@ public static String cleanPath(String path) {
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
- pathToUse = pathToUse.substring(prefixIndex + 1);
+ if (prefix.contains("/")) {
+ prefix = "";
+ }
+ else {
+ pathToUse = pathToUse.substring(prefixIndex + 1);
+ }
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
spring-core/src/test/java/org/springframework/util/StringUtilsTests.java+2 0
@@ -299,6 +299,8 @@ public void testCleanPath() {
assertEquals("../mypath/myfile", StringUtils.cleanPath("../mypath/../mypath/myfile"));
assertEquals("../mypath/myfile", StringUtils.cleanPath("mypath/../../mypath/myfile"));
assertEquals("/../mypath/myfile", StringUtils.cleanPath("/../mypath/myfile"));
+ assertEquals("/mypath/myfile", StringUtils.cleanPath("/a/:b/../../mypath/myfile"));
+ assertEquals("file:///c:/path/to/the%20file.txt", StringUtils.cleanPath("file:///c:/some/../path/to/the%20file.txt"));
}
public void testPathEquals() {

References