Skip to content

Commit ead224c

Browse files
Jami CogswellJami Cogswell
authored andcommitted
Java: expand qhelp, include Stapler examples
1 parent 096f6f8 commit ead224c

7 files changed

+86
-23
lines changed

java/ql/src/Security/CWE/CWE-352/CsrfUnprotectedRequestType.qhelp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,32 @@ result in exposure of data or unintended code execution.</p>
1010
</overview>
1111

1212
<recommendation>
13-
<p>When handling requests, make sure any requests that change application state are protected from
14-
Cross Site Request Forgery (CSRF). Some application frameworks, such as Spring, provide default CSRF
15-
protection for HTTP request types that may change application state, such as POST. Other HTTP request
16-
types, such as GET, should not be used for actions that change the state of the application, since these
17-
request types are not default-protected from CSRF by the framework.</p>
13+
<p>Make sure any requests that change application state are protected from Cross Site Request Forgery (CSRF).
14+
Some application frameworks provide default CSRF protection for unsafe HTTP request methods (<code>POST</code>,
15+
<code>PUT</code>, <code>DELETE</code>, <code>PATCH</code>, <code>CONNECT</code>) which may change the state of
16+
the application. Safe HTTP request methods (<code>GET</code>, <code>HEAD</code>, <code>OPTIONS</code>,
17+
<code>TRACE</code>) should be read-only and should not be used for actions that change application state.</p>
18+
19+
<p>This query currently supports the Spring and Stapler web frameworks. Spring provides default CSRF protection
20+
for all unsafe HTTP methods. Stapler provides default CSRF protection for the <code>POST</code> method.</p>
1821
</recommendation>
1922

2023
<example>
21-
<p>The following example shows a Spring request handler using a GET request for a state-changing action.
22-
Since a GET request does not have default CSRF protection in Spring, this type of request should
23-
not be used when modifying application state. Instead use one of Spring's default-protected request
24-
types, such as POST.</p>
24+
<p> The following examples show Spring request handlers allowing safe HTTP request methods for state-changing actions.
25+
Since safe HTTP request methods do not have default CSRF protection in Spring, they should not be used when modifying
26+
application state. Instead use one of the unsafe HTTP methods which Spring default-protects from CSRF.</p>
27+
28+
<sample src="CsrfUnprotectedRequestTypeBadSpring.java" />
29+
30+
<sample src="CsrfUnprotectedRequestTypeGoodSpring.java" />
31+
32+
<p> The following examples show Stapler web methods allowing safe HTTP request methods for state-changing actions.
33+
Since safe HTTP request methods do not have default CSRF protection in Stapler, they should not be used when modifying
34+
application state. Instead use the <code>POST</code> method which Stapler default-protects from CSRF.</p>
2535

26-
<sample src="CsrfUnprotectedRequestTypeBad.java" />
36+
<sample src="CsrfUnprotectedRequestTypeBadStapler.java" />
2737

28-
<sample src="CsrfUnprotectedRequestTypeGood.java" />
38+
<sample src="CsrfUnprotectedRequestTypeGoodStapler.java" />
2939
</example>
3040

3141
<references>
@@ -36,8 +46,17 @@ OWASP:
3646
<li>
3747
Spring Security Reference:
3848
<a href="https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html">
39-
Cross Site Request Forgery (CSRF)
40-
</a>.
49+
Cross Site Request Forgery (CSRF)</a>.
50+
</li>
51+
<li>
52+
Jenkins Developer Documentation:
53+
<a href="https://www.jenkins.io/doc/developer/security/form-validation/#protecting-from-csrf">
54+
Protecting from CSRF</a>.
55+
</li>
56+
<li>
57+
MDN web docs:
58+
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">
59+
HTTP request methods</a>.
4160
</li>
4261
</references>
4362
</qhelp>

java/ql/src/Security/CWE/CWE-352/CsrfUnprotectedRequestTypeBad.java

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import org.springframework.web.bind.annotation.RequestMapping;
2+
import org.springframework.web.bind.annotation.RequestMethod;
3+
4+
// BAD - a safe HTTP request like GET should not be used for a state-changing action
5+
@RequestMapping(value="/transfer", method=RequestMethod.GET)
6+
public boolean doTransfer(HttpServletRequest request, HttpServletResponse response){
7+
return transfer(request, response);
8+
}
9+
10+
// BAD - no HTTP request type is specified, so safe HTTP requests are allowed
11+
@RequestMapping(value="/delete")
12+
public boolean doDelete(HttpServletRequest request, HttpServletResponse response){
13+
return delete(request, response);
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import org.kohsuke.stapler.verb.GET;
2+
3+
// BAD - a safe HTTP request like GET should not be used for a state-changing action
4+
@GET
5+
public HttpRedirect doTransfer() {
6+
return transfer();
7+
}
8+
9+
// BAD - no HTTP request type is specified, so safe HTTP requests are allowed
10+
public HttpRedirect doDelete() {
11+
return delete();
12+
}

java/ql/src/Security/CWE/CWE-352/CsrfUnprotectedRequestTypeGood.java

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import org.springframework.web.bind.annotation.RequestMapping;
2+
import org.springframework.web.bind.annotation.RequestMethod;
3+
import org.springframework.web.bind.annotation.DeleteMapping;
4+
5+
// GOOD - use an unsafe HTTP request like POST
6+
@RequestMapping(value="/transfer", method=RequestMethod.POST)
7+
public boolean doTransfer(HttpServletRequest request, HttpServletResponse response){
8+
return transfer(request, response);
9+
}
10+
11+
// GOOD - use an unsafe HTTP request like DELETE
12+
@DeleteMapping(value="/delete")
13+
public boolean doDelete(HttpServletRequest request, HttpServletResponse response){
14+
return delete(request, response);
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import org.kohsuke.stapler.verb.POST;
2+
3+
// GOOD - use POST
4+
@POST
5+
public HttpRedirect doTransfer() {
6+
return transfer();
7+
}
8+
9+
// GOOD - use POST
10+
@POST
11+
public HttpRedirect doDelete() {
12+
return delete();
13+
}

0 commit comments

Comments
 (0)