Skip to content

Commit 530103e

Browse files
Jami CogswellJami Cogswell
authored andcommitted
Java: narrow query
remove PUT and DELETE from StaplerCsrfUnprotectedMethod remove OPTIONS and TRACE from SpringCsrfUnprotectedMethod
1 parent ead224c commit 530103e

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

java/ql/lib/semmle/code/java/security/CsrfUnprotectedRequestTypeQuery.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private class SpringCsrfUnprotectedMethod extends CsrfUnprotectedMethod instance
2525
or
2626
this.hasAnnotation("org.springframework.web.bind.annotation", "RequestMapping") and
2727
(
28-
this.getMethodValue() = ["GET", "HEAD", "OPTIONS", "TRACE"]
28+
this.getMethodValue() = ["GET", "HEAD"]
2929
or
3030
// If no request type is specified with `@RequestMapping`, then all request types
3131
// are possible, so we treat this as unsafe; example: @RequestMapping(value = "test").
@@ -43,7 +43,10 @@ private class StaplerCsrfUnprotectedMethod extends CsrfUnprotectedMethod instanc
4343
{
4444
StaplerCsrfUnprotectedMethod() {
4545
not this.hasAnnotation("org.kohsuke.stapler.interceptor", "RequirePOST") and
46-
not this.hasAnnotation("org.kohsuke.stapler.verb", "POST")
46+
// Jenkins only explicitly protects against CSRF for POST requests, but we
47+
// also exclude PUT and DELETE since these request types are only exploitable
48+
// if there is a CORS issue.
49+
not this.hasAnnotation("org.kohsuke.stapler.verb", ["POST", "PUT", "DELETE"])
4750
}
4851
}
4952

java/ql/test/query-tests/security/CWE-352/CsrfUnprotectedRequestTypeTest.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ public void bad5() { // $ hasCsrfUnprotectedRequestType
8888
} catch (SQLException e) { }
8989
}
9090

91+
// GOOD: uses OPTIONS or TRACE, which are unlikely to be exploitable via CSRF
92+
@RequestMapping(value = "", method = { OPTIONS, TRACE })
93+
public void good0() {
94+
try {
95+
String sql = "DELETE";
96+
Connection conn = DriverManager.getConnection("url");
97+
PreparedStatement ps = conn.prepareStatement(sql);
98+
ps.executeUpdate(); // database update method call
99+
} catch (SQLException e) { }
100+
}
101+
91102
// GOOD: uses POST request when updating a database
92103
@RequestMapping(value = "", method = RequestMethod.POST)
93104
public void good1() {
@@ -430,11 +441,10 @@ public String doPost3(String user) { // $ hasCsrfUnprotectedRequestType
430441
return "post";
431442
}
432443

433-
// BAD: Stapler web method annotated with `@PUT` and method name that implies a state-change
434-
// We treat this case as bad for Stapler since the Jenkins docs only say that @POST/@RequirePOST
435-
// provide default protection against CSRF.
444+
// GOOD: Stapler web method annotated with `@PUT` and method name that implies a state-change
445+
// We treat this case as good since PUT is only exploitable if there is a CORS issue.
436446
@PUT
437-
public String doPut(String user) { // $ hasCsrfUnprotectedRequestType
447+
public String doPut(String user) {
438448
return "put";
439449
}
440450

0 commit comments

Comments
 (0)