]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22329 Fix URL sanitization logic for OAuth2 authentication params.
authorDimitris Kavvathas <dimitris.kavvathas@sonarsource.com>
Thu, 13 Jun 2024 13:07:04 +0000 (15:07 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 14 Jun 2024 20:02:40 +0000 (20:02 +0000)
server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/OAuth2AuthenticationParametersImpl.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/OAuth2AuthenticationParametersImplTest.java

index 7be6aed2680b1a52c2ecaae3e87077b5018da560..fb890b212834d4481dfc6f1fdc400a1a74018bb6 100644 (file)
@@ -24,6 +24,8 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.Map;
@@ -131,11 +133,17 @@ public class OAuth2AuthenticationParametersImpl implements OAuth2AuthenticationP
       return empty();
     }
 
-    Path sanitizedPath = escapePathTraversalChars(trimmedUrl);
-    return Optional.of(sanitizedPath.toString());
+    try {
+      URI uri = new URI(trimmedUrl);
+      String sanitizedPath = escapePathTraversalChars(uri.getPath());
+      URI sanitizedUri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), sanitizedPath, uri.getQuery(), uri.getFragment());
+      return Optional.of(sanitizedUri.toString());
+    } catch (URISyntaxException e) {
+      throw new IllegalStateException(e);
+    }
   }
 
-  private static Path escapePathTraversalChars(String sanitizedUrl) {
-    return Path.of(sanitizedUrl).normalize();
+  private static String escapePathTraversalChars(String path) {
+    return Path.of(path).normalize().toString();
   }
 }
index 4c9b4d4b2fb7677b6eb2b9d6d18b67dc83cfc242..c3d2ddc05b821f83f4a7e17f7c58bfd8b35ba1bd 100644 (file)
@@ -157,6 +157,8 @@ public class OAuth2AuthenticationParametersImplTest {
       {generatePath("/admin/..%2fsettings/"), "/settings"},
       {generatePath("/admin/%2e%2e%2fsettings/"), "/settings"},
       {generatePath("../admin/settings"), null},
+      {generatePath("/dashboard?id=project&pullRequest=PRID"), "/dashboard?id=project&pullRequest=PRID"},
+      {generatePath("%2Fdashboard%3Fid%3Dproject%26pullRequest%3DPRID&authorizationError=true"), "/dashboard?id=project&pullRequest=PRID&authorizationError=true"},
     };
   }