mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Sensitive GET Query
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
public class SensitiveGetQuery extends HttpServlet {
|
||||
// BAD - Tests sending sensitive information in a GET request.
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
String password = request.getParameter("password");
|
||||
System.out.println("password = " + password);
|
||||
}
|
||||
|
||||
// GOOD - Tests sending sensitive information in a POST request.
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
String password = request.getParameter("password");
|
||||
System.out.println("password = " + password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Sensitive information like user passwords is transmitted within the query string of the requested URL in GET requests. Sensitive information within URLs may be logged in various locations, including the user's browser, the web server, and any forward or reverse proxy servers between the two endpoints. URLs may also be displayed on-screen, bookmarked or emailed around by users. They may be disclosed to third parties via the Referer header when any off-site links are followed. Placing passwords into the URL increases the risk that they will be captured by an attacker.</p>
|
||||
|
||||
<p>Vulnerabilities that result in the disclosure of users' passwords can result in compromises that are extremely difficult to investigate due to obscured audit trails. Even if an application itself only handles non-sensitive information, exposing passwords puts users who have re-used their password elsewhere at risk.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Use HTTP POST to send sensitive information either in web forms or REST web services calls.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example shows two ways of sending sensitive information. In the 'BAD' case, password is transmitted using the GET method. In the 'GOOD' case, the password is transmitted using the POST method.</p>
|
||||
<sample src="SensitiveGetQuery.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
CWE:
|
||||
<a href="https://cwe.mitre.org/data/definitions/598.html">CWE-598: Use of GET Request Method with Sensitive Query Strings</a>
|
||||
</li>
|
||||
<li>
|
||||
PortSwigger (Burp):
|
||||
<a href="https://portswigger.net/kb/issues/00400300_password-submitted-using-get-method">Password Submitted using GET Method</a>
|
||||
</li>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url">Information Exposure through Query Strings in URL</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @name Sensitive GET Query
|
||||
* @description Use of GET request method with sensitive query strings.
|
||||
* @kind path-problem
|
||||
* @id java/sensitive-query-with-get
|
||||
* @tags security
|
||||
* external/cwe-598
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.frameworks.Servlets
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/** Finds variables that hold sensitive information judging by their names. */
|
||||
class SensitiveInfoExpr extends Expr {
|
||||
SensitiveInfoExpr() {
|
||||
exists(Variable v | this = v.getAnAccess() |
|
||||
v.getName().regexpMatch(getCommonSensitiveInfoRegex())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** GET servlet method of `javax.servlet.http.Servlet` and subtypes. */
|
||||
private predicate isGetServletMethod(Callable c) {
|
||||
c.getDeclaringType() instanceof ServletClass and
|
||||
c.getNumberOfParameters() = 2 and
|
||||
c.getParameter(1).getType() instanceof ServletResponse and
|
||||
c.getName() = "doGet"
|
||||
}
|
||||
|
||||
/** Sink of GET servlet requests. */
|
||||
class GetServletMethodSink extends DataFlow::ExprNode {
|
||||
GetServletMethodSink() {
|
||||
exists(Method m, MethodAccess ma | ma.getMethod() = m |
|
||||
isGetServletMethod(ma.getEnclosingCallable()) and
|
||||
ma.getAnArgument() = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Taint configuration of using GET requests with sensitive query strings. */
|
||||
class SensitiveGetQueryConfiguration extends TaintTracking::Configuration {
|
||||
SensitiveGetQueryConfiguration() { this = "SensitiveGetQueryConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof SensitiveInfoExpr
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof GetServletMethodSink }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveGetQueryConfiguration c
|
||||
where c.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ uses GET request method with sensitive information.",
|
||||
source.getNode(), "sensitive query string"
|
||||
@@ -0,0 +1,7 @@
|
||||
edges
|
||||
| SensitiveGetQuery.java:12:38:12:45 | password : String | SensitiveGetQuery.java:12:22:12:45 | ... + ... |
|
||||
nodes
|
||||
| SensitiveGetQuery.java:12:22:12:45 | ... + ... | semmle.label | ... + ... |
|
||||
| SensitiveGetQuery.java:12:38:12:45 | password : String | semmle.label | password : String |
|
||||
#select
|
||||
| SensitiveGetQuery.java:12:22:12:45 | ... + ... | SensitiveGetQuery.java:12:38:12:45 | password : String | SensitiveGetQuery.java:12:22:12:45 | ... + ... | $@ uses GET request method with sensitive information. | SensitiveGetQuery.java:12:38:12:45 | password | sensitive query string |
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
public class SensitiveGetQuery extends HttpServlet {
|
||||
// BAD - Tests sending sensitive information in a GET request.
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
String password = request.getParameter("password");
|
||||
System.out.println("password = " + password);
|
||||
}
|
||||
|
||||
// GOOD - Tests sending sensitive information in a POST request.
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
String password = request.getParameter("password");
|
||||
System.out.println("password = " + password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-598/SensitiveGetQuery.ql
|
||||
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4
|
||||
Reference in New Issue
Block a user