diff --git a/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal.go b/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal.go index ccfa64aa..f966bf83 100644 --- a/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal.go +++ b/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal.go @@ -21,7 +21,7 @@ func detectPathTraversal(filePath string, userInput string, checkPathStart bool) return false } - if !strings.Contains(filePath, userInput) { + if !strings.Contains(strings.ToLower(filePath), strings.ToLower(userInput)) { // We ignore cases where the user input is not part of the file path. return false } diff --git a/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal_test.go b/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal_test.go index 2489cb5f..bdd0c4d0 100644 --- a/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal_test.go +++ b/lib/request-processor/vulnerabilities/path-traversal/detectPathTraversal_test.go @@ -237,4 +237,21 @@ func TestDetectPathTraversal(t *testing.T) { } } }) + + t.Run("case-insensitive path containment detects traversal on case-insensitive filesystems", func(t *testing.T) { + testCases := []struct { + inputPath string + userPath string + expected bool + }{ + {"/etc/passwd", "/ETC/passwd", true}, + {"/etc/passwd", "/ETC/PASSWD", true}, + {"/home/user/file.txt", "/HOME/USER/file.txt", true}, + } + for _, tc := range testCases { + if detectPathTraversal(tc.inputPath, tc.userPath, true) != tc.expected { + t.Errorf("expected %v for input %q and user path %q", tc.expected, tc.inputPath, tc.userPath) + } + } + }) }