mirror of
https://github.com/github/codeql.git
synced 2026-04-20 06:24:03 +02:00
Merge pull request #18288 from jcogs33/jcogs33/csrf-unprotected-request-type
Java: add CSRF query
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE qhelp SYSTEM "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Cross-site request forgery (CSRF) is a type of vulnerability in which an
|
||||
attacker is able to force a user to carry out an action that the user did
|
||||
not intend.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The attacker tricks an authenticated user into submitting a request to the
|
||||
web application. Typically, this request will result in a state change on
|
||||
the server, such as changing the user's password. The request can be
|
||||
initiated when the user visits a site controlled by the attacker. If the
|
||||
web application relies only on cookies for authentication, or on other
|
||||
credentials that are automatically included in the request, then this
|
||||
request will appear as legitimate to the server.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Make sure any requests that change application state are protected from CSRF. Some application
|
||||
frameworks provide default CSRF protection for unsafe HTTP request methods (such as <code>POST</code>)
|
||||
which may change the state of the application. Safe HTTP request methods (such as <code>GET</code>)
|
||||
should only perform read-only operations and should not be used for actions that change application
|
||||
state.</p>
|
||||
|
||||
<p>This query currently supports the Spring and Stapler web frameworks. Spring provides default CSRF protection
|
||||
for all unsafe HTTP methods whereas Stapler provides default CSRF protection for the <code>POST</code> method.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p> The following examples show Spring request handlers allowing safe HTTP request methods for state-changing actions.
|
||||
Since safe HTTP request methods do not have default CSRF protection in Spring, they should not be used when modifying
|
||||
application state. Instead, use one of the unsafe HTTP methods which Spring default-protects from CSRF.</p>
|
||||
|
||||
<sample src="CsrfUnprotectedRequestTypeBadSpring.java" />
|
||||
|
||||
<sample src="CsrfUnprotectedRequestTypeGoodSpring.java" />
|
||||
|
||||
<p> The following examples show Stapler web methods allowing safe HTTP request methods for state-changing actions.
|
||||
Since safe HTTP request methods do not have default CSRF protection in Stapler, they should not be used when modifying
|
||||
application state. Instead, use the <code>POST</code> method which Stapler default-protects from CSRF.</p>
|
||||
|
||||
<sample src="CsrfUnprotectedRequestTypeBadStapler.java" />
|
||||
|
||||
<sample src="CsrfUnprotectedRequestTypeGoodStapler.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)">Cross Site Request Forgery (CSRF)</a>.
|
||||
</li>
|
||||
<li>
|
||||
Spring Security Reference:
|
||||
<a href="https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html">
|
||||
Cross Site Request Forgery (CSRF)</a>.
|
||||
</li>
|
||||
<li>
|
||||
Jenkins Developer Documentation:
|
||||
<a href="https://www.jenkins.io/doc/developer/security/form-validation/#protecting-from-csrf">
|
||||
Protecting from CSRF</a>.
|
||||
</li>
|
||||
<li>
|
||||
MDN web docs:
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">
|
||||
HTTP request methods</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @name HTTP request type unprotected from CSRF
|
||||
* @description Using an HTTP request type that is not default-protected from CSRF for a
|
||||
* state-changing action makes the application vulnerable to a Cross-Site
|
||||
* Request Forgery (CSRF) attack.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 8.8
|
||||
* @precision medium
|
||||
* @id java/csrf-unprotected-request-type
|
||||
* @tags security
|
||||
* external/cwe/cwe-352
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CsrfUnprotectedRequestTypeQuery
|
||||
|
||||
query predicate edges(CallPathNode pred, CallPathNode succ) { CallGraph::edges(pred, succ) }
|
||||
|
||||
from CallPathNode source, CallPathNode sink
|
||||
where unprotectedStateChange(source, sink)
|
||||
select source.asMethod(), source, sink,
|
||||
"Potential CSRF vulnerability due to using an HTTP request type which is not default-protected from CSRF for an apparent $@.",
|
||||
sink, "state-changing action"
|
||||
@@ -0,0 +1,14 @@
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
// BAD - a safe HTTP request like GET should not be used for a state-changing action
|
||||
@RequestMapping(value="/transfer", method=RequestMethod.GET)
|
||||
public boolean doTransfer(HttpServletRequest request, HttpServletResponse response){
|
||||
return transfer(request, response);
|
||||
}
|
||||
|
||||
// BAD - no HTTP request type is specified, so safe HTTP requests are allowed
|
||||
@RequestMapping(value="/delete")
|
||||
public boolean doDelete(HttpServletRequest request, HttpServletResponse response){
|
||||
return delete(request, response);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.kohsuke.stapler.verb.GET;
|
||||
|
||||
// BAD - a safe HTTP request like GET should not be used for a state-changing action
|
||||
@GET
|
||||
public HttpRedirect doTransfer() {
|
||||
return transfer();
|
||||
}
|
||||
|
||||
// BAD - no HTTP request type is specified, so safe HTTP requests are allowed
|
||||
public HttpRedirect doPost() {
|
||||
return post();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
|
||||
// GOOD - use an unsafe HTTP request like POST
|
||||
@RequestMapping(value="/transfer", method=RequestMethod.POST)
|
||||
public boolean doTransfer(HttpServletRequest request, HttpServletResponse response){
|
||||
return transfer(request, response);
|
||||
}
|
||||
|
||||
// GOOD - use an unsafe HTTP request like DELETE
|
||||
@DeleteMapping(value="/delete")
|
||||
public boolean doDelete(HttpServletRequest request, HttpServletResponse response){
|
||||
return delete(request, response);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import org.kohsuke.stapler.verb.POST;
|
||||
|
||||
// GOOD - use POST
|
||||
@POST
|
||||
public HttpRedirect doTransfer() {
|
||||
return transfer();
|
||||
}
|
||||
|
||||
// GOOD - use POST
|
||||
@POST
|
||||
public HttpRedirect doPost() {
|
||||
return post();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query, `java/csrf-unprotected-request-type`, to detect Cross-Site Request Forgery (CSRF) vulnerabilities due to using HTTP request types that are not default-protected from CSRF.
|
||||
@@ -4,7 +4,6 @@
|
||||
deprecated module;
|
||||
|
||||
import java
|
||||
import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.MyBatis
|
||||
import semmle.code.java.frameworks.Properties
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
import java
|
||||
deprecated import MyBatisCommonLib
|
||||
deprecated import MyBatisMapperXmlSqlInjectionLib
|
||||
deprecated import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.security.Sanitizers
|
||||
deprecated import MyBatisMapperXmlSqlInjectionFlow::PathGraph
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
deprecated module;
|
||||
|
||||
import java
|
||||
import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.frameworks.MyBatis
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.Properties
|
||||
|
||||
|
||||
Reference in New Issue
Block a user