This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new c6937f0c19 Fix security issue with malformed HTTP Method
c6937f0c19 is described below
commit c6937f0c198366ec44f3fa4ee2bf11ff485f5913
Author: James Bognar <[email protected]>
AuthorDate: Thu Dec 4 12:10:44 2025 -0800
Fix security issue with malformed HTTP Method
---
.../java/org/apache/juneau/rest/RestSession.java | 12 ++++++++++-
.../org/apache/juneau/rest/logger/CallLogger.java | 2 +-
.../annotation/Rest_AllowedMethodParams_Test.java | 23 ++++++++++++++++++++++
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
index 18e58231b4..6be399cf59 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
@@ -24,6 +24,7 @@ import java.util.*;
import org.apache.http.*;
import org.apache.juneau.*;
+import org.apache.juneau.commons.utils.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.http.response.*;
import org.apache.juneau.rest.annotation.*;
@@ -297,12 +298,15 @@ public class RestSession extends ContextSession {
*/
public Throwable getException() { return
(Throwable)req.getAttribute("Exception"); }
+ private static AsciiSet VALID_METHOD_CHARS =
AsciiSet.create().ranges("A-Z", "a-z" ,"0-9").chars("_-").build();
+
/**
* Returns the HTTP method name.
*
* @return The HTTP method name, always uppercased.
+ * @throws NotFound If the method parameter contains invalid/malformed
characters.
*/
- public String getMethod() {
+ public String getMethod() throws NotFound {
if (method == null) {
Set<String> s1 = context.getAllowedMethodParams();
@@ -312,12 +316,18 @@ public class RestSession extends ContextSession {
String[] x = getQueryParams().get("method");
if (nn(x) && (s1.contains("*") ||
s1.contains(x[0])))
method = x[0];
+ if (method != null && !
VALID_METHOD_CHARS.containsOnly(method)) {
+ throw new MethodNotAllowed();
+ }
}
if (method == null && ! s2.isEmpty()) {
var x = req.getHeader("X-Method");
if (nn(x) && (s2.contains("*") ||
s2.contains(x)))
method = x;
+ if (method != null && !
VALID_METHOD_CHARS.containsOnly(method)) {
+ throw new MethodNotAllowed();
+ }
}
if (method == null)
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
index 74ed858bde..a2a71fe237 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
@@ -576,7 +576,7 @@ public class CallLogger {
if (nn(sti)) {
var count = sti.getCount();
-
sb.append(',').append(StringUtils.toHex8(sti.getHash())).append('.').append(count);
+
sb.append(',').append(StringUtils.toHex8(Math.abs(sti.getHash()))).append('.').append(count);
if (count > 1)
e = null;
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedMethodParams_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedMethodParams_Test.java
index 895bc9b270..6e4d192193 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedMethodParams_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedMethodParams_Test.java
@@ -165,4 +165,27 @@ class Rest_AllowedMethodParams_Test extends TestBase {
a8.get("/?method=OPTIONS").run().assertContent("GET");
a8.request("get","/?method=FOO").run().assertContent("GET");
}
+
+
//------------------------------------------------------------------------------------------------------------------
+ // Security: Malformed method parameters should return 405, not 500
(CWE-74)
+
//------------------------------------------------------------------------------------------------------------------
+
+ @Test void b01_malformedMethodParameter_returns405() throws Exception {
+ var a5 = MockRestClient.build(A5.class);
+
+ // Test various malformed method parameters that should return
404
+ // These contain special characters that indicate
malformed/encoded input
+
a5.get("/?method=VIEW%5C%5C%5C%22&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW\\\"&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW%22&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW<script>&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW/test&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW%2Ftest&noTrace=true").ignoreErrors().run().assertStatus(405);
+ // Test with spaces and other invalid characters
+ a5.get("/?method=VIEW
test&noTrace=true").ignoreErrors().run().assertStatus(405);
+
a5.get("/?method=VIEW+test&noTrace=true").ignoreErrors().run().assertStatus(405);
+ // Valid method parameters should still work
+ a5.get("/?method=VIEW").ignoreErrors().run().assertStatus(405);
// 405 because VIEW method doesn't exist, but not 500
+ a5.get("/?method=FOO").run().assertContent("FOO"); // Valid
method works
+ }
}
\ No newline at end of file