mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into santander-java-crypto-check
This commit is contained in:
@@ -1,12 +1,29 @@
|
||||
import subprocess
|
||||
import logging
|
||||
import time
|
||||
import socket
|
||||
|
||||
|
||||
def wait_for_port(port, process, timeout=100):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
# Check if process died
|
||||
if process.poll() is not None:
|
||||
raise RuntimeError(f"Server process exited with code {process.returncode}")
|
||||
try:
|
||||
with socket.create_connection(("localhost", port), timeout=1):
|
||||
return True
|
||||
except (socket.timeout, ConnectionRefusedError, OSError):
|
||||
time.sleep(0.2)
|
||||
raise RuntimeError(f"Port {port} not ready within {timeout}s")
|
||||
|
||||
|
||||
def test(codeql, java):
|
||||
# Each of these serves the "repo" and "repo2" directories on http://localhost:924[89]
|
||||
repo_server_process = subprocess.Popen(["python3", "-m", "http.server", "9428", "-b", "localhost"], cwd="repo")
|
||||
repo_server_process2 = subprocess.Popen(["python3", "-m", "http.server", "9429", "-b", "localhost"], cwd="repo2")
|
||||
repo_server_process = subprocess.Popen(["python3", "-m", "http.server", "9428", "-b", "localhost"], cwd="repo", stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
repo_server_process2 = subprocess.Popen(["python3", "-m", "http.server", "9429", "-b", "localhost"], cwd="repo2", stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
try:
|
||||
wait_for_port(9428, repo_server_process)
|
||||
wait_for_port(9429, repo_server_process2)
|
||||
codeql.database.create(
|
||||
extractor_option="buildless=true",
|
||||
_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"},
|
||||
|
||||
@@ -21,6 +21,7 @@ ql/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1104/MavenPomDependsOnBintray.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/NettyResponseSplitting.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql
|
||||
|
||||
@@ -127,6 +127,7 @@ ql/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1104/MavenPomDependsOnBintray.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/NettyResponseSplitting.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql
|
||||
|
||||
@@ -30,6 +30,7 @@ ql/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-1104/MavenPomDependsOnBintray.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/NettyResponseSplitting.ql
|
||||
ql/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql
|
||||
|
||||
@@ -190,7 +190,6 @@ ql/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-094/SpringImplicitViewManipulation.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulation.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-1004/InsecureTomcatConfig.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-200/InsecureWebResourceResponse.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-200/SensitiveAndroidFileLeak.ql
|
||||
ql/java/ql/src/experimental/Security/CWE/CWE-208/PossibleTimingAttackAgainstSignature.ql
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 7.7.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fields of certain objects are considered tainted if the object is tainted. This holds, for example, for objects that occur directly as sources in the active threat model (for instance, a remote flow source). This has now been amended to also include array types, such that if an array like `MyPojo[]` is a source, then fields of a tainted `MyPojo` are now also considered tainted.
|
||||
|
||||
## 7.7.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 7.7.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fields of certain objects are considered tainted if the object is tainted. This holds, for example, for objects that occur directly as sources in the active threat model (for instance, a remote flow source). This has now been amended to also include array types, such that if an array like `MyPojo[]` is a source, then fields of a tainted `MyPojo` are now also considered tainted.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.7.1
|
||||
lastReleaseVersion: 7.7.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-all
|
||||
version: 7.7.2-dev
|
||||
version: 7.7.3-dev
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.8.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Cross-Site Scripting (XSS) is categorized as one of the OWASP Top 10 Security Vulnerabilities. The <code>HttpOnly</code> flag directs compatible browsers to prevent client-side script from accessing cookies. Including the <code>HttpOnly</code> flag in the Set-Cookie HTTP response header for a sensitive cookie helps mitigate the risk associated with XSS where an attacker's script code attempts to read the contents of a cookie and exfiltrate information obtained.</p>
|
||||
<p>Cookies without the <code>HttpOnly</code> flag set are accessible to client-side scripts (such as JavaScript) running in the same origin.
|
||||
In case of a Cross-Site Scripting (XSS) vulnerability, the cookie can be stolen by a malicious script.
|
||||
If a sensitive cookie does not need to be accessed directly by client-side scripts, the <code>HttpOnly</code> flag should be set.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Use the <code>HttpOnly</code> flag when generating a cookie containing sensitive information to help mitigate the risk of client side script accessing the protected cookie.</p>
|
||||
<p>Use the <code>HttpOnly</code> flag when generating a cookie containing sensitive information to help mitigate the risk of client-side scripts accessing the protected cookie.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
@@ -23,5 +25,6 @@
|
||||
OWASP:
|
||||
<a href="https://owasp.org/www-community/HttpOnly">HttpOnly</a>
|
||||
</li>
|
||||
<li>MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#httponly">Set-Cookie HttpOnly</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @name Sensitive cookies without the HttpOnly response header set
|
||||
* @description Sensitive cookies without the 'HttpOnly' flag set leaves session cookies vulnerable to
|
||||
* @description A sensitive cookie without the 'HttpOnly' flag set may be vulnerable to
|
||||
* an XSS attack.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @security-severity 5.0
|
||||
* @id java/sensitive-cookie-not-httponly
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-1004
|
||||
*/
|
||||
|
||||
@@ -15,16 +15,15 @@
|
||||
* Sketch of the structure of this query: we track cookie names that appear to be sensitive
|
||||
* (e.g. `session` or `token`) to a `ServletResponse.addHeader(...)` or `.addCookie(...)`
|
||||
* method that does not set the `httpOnly` flag. Subsidiary configurations
|
||||
* `MatchesHttpOnlyConfiguration` and `SetHttpOnlyInCookieConfiguration` are used to establish
|
||||
* `MatchesHttpOnlyToRawHeaderConfig` and `SetHttpOnlyInCookieConfig` are used to establish
|
||||
* when the `httpOnly` flag is likely to have been set, before configuration
|
||||
* `MissingHttpOnlyConfiguration` establishes that a non-`httpOnly` cookie has a sensitive-seeming name.
|
||||
* `MissingHttpOnlyConfig` establishes that a non-`httpOnly` cookie has a sensitive-seeming name.
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
import semmle.code.java.frameworks.Servlets
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import MissingHttpOnlyFlow::PathGraph
|
||||
|
||||
/** Gets a regular expression for matching common names of sensitive cookies. */
|
||||
string getSensitiveCookieNameRegex() { result = "(?i).*(auth|session|token|key|credential).*" }
|
||||
@@ -50,8 +49,8 @@ class SensitiveCookieNameExpr extends Expr {
|
||||
}
|
||||
|
||||
/** A method call that sets a `Set-Cookie` header. */
|
||||
class SetCookieMethodCall extends MethodCall {
|
||||
SetCookieMethodCall() {
|
||||
class SetCookieRawHeaderMethodCall extends MethodCall {
|
||||
SetCookieRawHeaderMethodCall() {
|
||||
(
|
||||
this.getMethod() instanceof ResponseAddHeaderMethod or
|
||||
this.getMethod() instanceof ResponseSetHeaderMethod
|
||||
@@ -62,19 +61,19 @@ class SetCookieMethodCall extends MethodCall {
|
||||
|
||||
/**
|
||||
* A taint configuration tracking flow from the text `httponly` to argument 1 of
|
||||
* `SetCookieMethodCall`.
|
||||
* `SetCookieRawHeaderMethodCall`.
|
||||
*/
|
||||
module MatchesHttpOnlyConfig implements DataFlow::ConfigSig {
|
||||
module MatchesHttpOnlyToRawHeaderConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().(CompileTimeConstantExpr).getStringValue().toLowerCase().matches("%httponly%")
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asExpr() = any(SetCookieMethodCall ma).getArgument(1)
|
||||
sink.asExpr() = any(SetCookieRawHeaderMethodCall ma).getArgument(1)
|
||||
}
|
||||
}
|
||||
|
||||
module MatchesHttpOnlyFlow = TaintTracking::Global<MatchesHttpOnlyConfig>;
|
||||
module MatchesHttpOnlyToRawHeaderFlow = TaintTracking::Global<MatchesHttpOnlyToRawHeaderConfig>;
|
||||
|
||||
/** A class descended from `javax.servlet.http.Cookie`. */
|
||||
class CookieClass extends RefType {
|
||||
@@ -103,29 +102,11 @@ predicate removesCookie(MethodCall ma) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the MethodCall `ma` is a test method call indicated by:
|
||||
* a) in a test directory such as `src/test/java`
|
||||
* b) in a test package whose name has the word `test`
|
||||
* c) in a test class whose name has the word `test`
|
||||
* d) in a test class implementing a test framework such as JUnit or TestNG
|
||||
* A taint configuration tracking the flow of a cookie that has had the
|
||||
* `HttpOnly` flag set, or has been removed, to a `ServletResponse.addCookie`
|
||||
* call.
|
||||
*/
|
||||
predicate isTestMethod(MethodCall ma) {
|
||||
exists(Method m |
|
||||
m = ma.getEnclosingCallable() and
|
||||
(
|
||||
m.getDeclaringType().getName().toLowerCase().matches("%test%") or // Simple check to exclude test classes to reduce FPs
|
||||
m.getDeclaringType().getPackage().getName().toLowerCase().matches("%test%") or // Simple check to exclude classes in test packages to reduce FPs
|
||||
exists(m.getLocation().getFile().getAbsolutePath().indexOf("/src/test/java")) or // Match test directory structure of build tools like maven
|
||||
m instanceof TestMethod // Test method of a test case implementing a test framework such as JUnit or TestNG
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint configuration tracking flow of a method that sets the `HttpOnly` flag,
|
||||
* or one that removes a cookie, to a `ServletResponse.addCookie` call.
|
||||
*/
|
||||
module SetHttpOnlyOrRemovesCookieConfig implements DataFlow::ConfigSig {
|
||||
module SetHttpOnlyOrRemovesCookieToAddCookieConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() =
|
||||
any(MethodCall ma | setsCookieHttpOnly(ma) or removesCookie(ma)).getQualifier()
|
||||
@@ -137,25 +118,25 @@ module SetHttpOnlyOrRemovesCookieConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
}
|
||||
|
||||
module SetHttpOnlyOrRemovesCookieFlow = TaintTracking::Global<SetHttpOnlyOrRemovesCookieConfig>;
|
||||
module SetHttpOnlyOrRemovesCookieToAddCookieFlow =
|
||||
TaintTracking::Global<SetHttpOnlyOrRemovesCookieToAddCookieConfig>;
|
||||
|
||||
/**
|
||||
* A cookie that is added to an HTTP response and which doesn't have `httpOnly` set, used as a sink
|
||||
* in `MissingHttpOnlyConfiguration`.
|
||||
* A cookie that is added to an HTTP response and which doesn't have `HttpOnly` set, used as a sink
|
||||
* in `MissingHttpOnlyConfig`.
|
||||
*/
|
||||
class CookieResponseSink extends DataFlow::ExprNode {
|
||||
CookieResponseSink() {
|
||||
class CookieResponseWithoutHttpOnlySink extends DataFlow::ExprNode {
|
||||
CookieResponseWithoutHttpOnlySink() {
|
||||
exists(MethodCall ma |
|
||||
(
|
||||
ma.getMethod() instanceof ResponseAddCookieMethod and
|
||||
this.getExpr() = ma.getArgument(0) and
|
||||
not SetHttpOnlyOrRemovesCookieFlow::flowTo(this)
|
||||
not SetHttpOnlyOrRemovesCookieToAddCookieFlow::flowTo(this)
|
||||
or
|
||||
ma instanceof SetCookieMethodCall and
|
||||
ma instanceof SetCookieRawHeaderMethodCall and
|
||||
this.getExpr() = ma.getArgument(1) and
|
||||
not MatchesHttpOnlyFlow::flowTo(this) // response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure")
|
||||
) and
|
||||
not isTestMethod(ma) // Test class or method
|
||||
not MatchesHttpOnlyToRawHeaderFlow::flowTo(this) // response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -178,15 +159,21 @@ predicate setsHttpOnlyInNewCookie(ClassInstanceExpr cie) {
|
||||
|
||||
/**
|
||||
* A taint configuration tracking flow from a sensitive cookie without the `HttpOnly` flag
|
||||
* set to its HTTP response.
|
||||
* set to an HTTP response.
|
||||
*
|
||||
* Tracks string literals containing sensitive names (`SensitiveCookieNameExpr`), to an `addCookie` call (as a `Cookie` object)
|
||||
* or an `addHeader` call (as a string) (`CookieResponseWithoutHttpOnlySink`).
|
||||
*
|
||||
* Passes through `Cookie` constructors and `toString` calls.
|
||||
*/
|
||||
module MissingHttpOnlyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveCookieNameExpr }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof CookieResponseSink }
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof CookieResponseWithoutHttpOnlySink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
// JAX-RS's `new NewCookie("session-access-key", accessKey, "/", null, null, 0, true, true)` and similar
|
||||
// Cookie constructors that set the `HttpOnly` flag are considered barriers to the flow of sensitive names.
|
||||
setsHttpOnlyInNewCookie(node.asExpr())
|
||||
}
|
||||
|
||||
@@ -212,13 +199,8 @@ module MissingHttpOnlyConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module MissingHttpOnlyFlow = TaintTracking::Global<MissingHttpOnlyConfig>;
|
||||
|
||||
deprecated query predicate problems(
|
||||
DataFlow::Node sinkNode, MissingHttpOnlyFlow::PathNode source, MissingHttpOnlyFlow::PathNode sink,
|
||||
string message1, DataFlow::Node sourceNode, string message2
|
||||
) {
|
||||
MissingHttpOnlyFlow::flowPath(source, sink) and
|
||||
sinkNode = sink.getNode() and
|
||||
message1 = "$@ doesn't have the HttpOnly flag set." and
|
||||
sourceNode = source.getNode() and
|
||||
message2 = "This sensitive cookie"
|
||||
}
|
||||
import MissingHttpOnlyFlow::PathGraph
|
||||
|
||||
from MissingHttpOnlyFlow::PathNode source, MissingHttpOnlyFlow::PathNode sink
|
||||
where MissingHttpOnlyFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@ doesn't have the HttpOnly flag set.", source, "This sensitive cookie"
|
||||
@@ -3,11 +3,15 @@
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Using broken or weak cryptographic algorithms can leave data vulnerable to being decrypted.</p>
|
||||
<p>Using broken or weak cryptographic algorithms may compromise security guarantees such as confidentiality, integrity, and authenticity.</p>
|
||||
|
||||
<p>Many cryptographic algorithms provided by cryptography libraries are known to be weak, or
|
||||
flawed. Using such an algorithm means that an attacker may be able to easily decrypt the encrypted
|
||||
data.</p>
|
||||
<p>Many cryptographic algorithms are known to be weak or flawed. The security guarantees of a system often rely on the underlying cryptography, so using a weak algorithm can have severe consequences. For example:
|
||||
</p>
|
||||
<ul>
|
||||
<li>If a weak encryption algorithm is used, an attacker may be able to decrypt sensitive data.</li>
|
||||
<li>If a weak hashing algorithm is used to protect data integrity, an attacker may be able to craft a malicious input that has the same hash as a benign one.</li>
|
||||
<li>If a weak algorithm is used for digital signatures, an attacker may be able to forge signatures and impersonate legitimate users.</li>
|
||||
</ul>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* The `java/sensitive-cookie-not-httponly` query has been promoted from experimental to the main query pack.
|
||||
3
java/ql/src/change-notes/released/1.8.2.md
Normal file
3
java/ql/src/change-notes/released/1.8.2.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.8.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.8.1
|
||||
lastReleaseVersion: 1.8.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-queries
|
||||
version: 1.8.2-dev
|
||||
version: 1.8.3-dev
|
||||
groups:
|
||||
- java
|
||||
- queries
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
query: experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
postprocess: utils/test/PrettyPrintModels.ql
|
||||
@@ -1 +0,0 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jsr311-api-1.1.1:${testdir}/../../../../stubs/springframework-5.8.x
|
||||
@@ -1,3 +1,14 @@
|
||||
#select
|
||||
| SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | This sensitive cookie |
|
||||
edges
|
||||
| SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | SensitiveCookieNotHttpOnly.java:25:39:25:52 | tokenCookieStr : String | provenance | |
|
||||
| SensitiveCookieNotHttpOnly.java:25:28:25:64 | new Cookie(...) : Cookie | SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | provenance | Sink:MaD:1 |
|
||||
@@ -53,15 +64,4 @@ nodes
|
||||
| SensitiveCookieNotHttpOnly.java:91:16:91:21 | cookie : Cookie | semmle.label | cookie : Cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:110:25:110:64 | createAuthenticationCookie(...) : Cookie | semmle.label | createAuthenticationCookie(...) : Cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | semmle.label | cookie |
|
||||
problems
|
||||
| SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" : String | SensitiveCookieNotHttpOnly.java:31:28:31:36 | jwtCookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:24:33:24:43 | "jwt_token" | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:49 | "token=" | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... : String | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:57 | ... + ... | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:42:42:42:69 | ... + ... | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:52:42:52:124 | toString(...) | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:52:56:52:75 | "session-access-key" | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" : String | SensitiveCookieNotHttpOnly.java:65:42:65:47 | keyStr | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:63:51:63:70 | "session-access-key" | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:35 | "token=" | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:43 | ... + ... | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... : String | SensitiveCookieNotHttpOnly.java:71:42:71:50 | secString | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:70:28:70:55 | ... + ... | This sensitive cookie |
|
||||
| SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" : String | SensitiveCookieNotHttpOnly.java:111:28:111:33 | cookie | $@ doesn't have the HttpOnly flag set. | SensitiveCookieNotHttpOnly.java:88:35:88:51 | "Presto-UI-Token" | This sensitive cookie |
|
||||
subpaths
|
||||
@@ -21,14 +21,14 @@ class SensitiveCookieNotHttpOnly {
|
||||
|
||||
// BAD - Tests adding a sensitive cookie without the `HttpOnly` flag set.
|
||||
public void addCookie2(String jwt_token, String userId, HttpServletRequest request, HttpServletResponse response) {
|
||||
String tokenCookieStr = "jwt_token";
|
||||
String tokenCookieStr = "jwt_token"; // $Source
|
||||
Cookie jwtCookie = new Cookie(tokenCookieStr, jwt_token);
|
||||
Cookie userIdCookie = new Cookie("user_id", userId);
|
||||
jwtCookie.setPath("/");
|
||||
userIdCookie.setPath("/");
|
||||
jwtCookie.setMaxAge(3600*24*7);
|
||||
userIdCookie.setMaxAge(3600*24*7);
|
||||
response.addCookie(jwtCookie);
|
||||
response.addCookie(jwtCookie); // $Alert
|
||||
response.addCookie(userIdCookie);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class SensitiveCookieNotHttpOnly {
|
||||
|
||||
// BAD - Tests set a sensitive cookie header without the `HttpOnly` flag set.
|
||||
public void addCookie4(String authId, HttpServletRequest request, HttpServletResponse response) {
|
||||
response.addHeader("Set-Cookie", "token=" +authId + ";Secure");
|
||||
response.addHeader("Set-Cookie", "token=" +authId + ";Secure"); // $Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through string concatenation.
|
||||
@@ -49,7 +49,7 @@ class SensitiveCookieNotHttpOnly {
|
||||
|
||||
// BAD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` without the `HttpOnly` flag set.
|
||||
public void addCookie6(String accessKey, HttpServletRequest request, HttpServletResponse response) {
|
||||
response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true).toString());
|
||||
response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true).toString()); // $Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through the constructor.
|
||||
@@ -60,15 +60,15 @@ class SensitiveCookieNotHttpOnly {
|
||||
|
||||
// BAD - Tests set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` without the `HttpOnly` flag set.
|
||||
public void addCookie8(String accessKey, HttpServletRequest request, HttpServletResponse response) {
|
||||
NewCookie accessKeyCookie = new NewCookie("session-access-key", accessKey, "/", null, 0, null, 86400, true);
|
||||
NewCookie accessKeyCookie = new NewCookie("session-access-key", accessKey, "/", null, 0, null, 86400, true); // $Source
|
||||
String keyStr = accessKeyCookie.toString();
|
||||
response.setHeader("Set-Cookie", keyStr);
|
||||
response.setHeader("Set-Cookie", keyStr); // $Alert
|
||||
}
|
||||
|
||||
// BAD - Tests set a sensitive cookie header using a variable without the `HttpOnly` flag set.
|
||||
public void addCookie9(String authId, HttpServletRequest request, HttpServletResponse response) {
|
||||
String secString = "token=" +authId + ";Secure";
|
||||
response.addHeader("Set-Cookie", secString);
|
||||
String secString = "token=" +authId + ";Secure"; // $Source
|
||||
response.addHeader("Set-Cookie", secString); // $Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests set a sensitive cookie header with the `HttpOnly` flag set using `String.format(...)`.
|
||||
@@ -85,7 +85,7 @@ class SensitiveCookieNotHttpOnly {
|
||||
}
|
||||
|
||||
public Cookie createAuthenticationCookie(HttpServletRequest request, String jwt) {
|
||||
String PRESTO_UI_COOKIE = "Presto-UI-Token";
|
||||
String PRESTO_UI_COOKIE = "Presto-UI-Token"; // $Source
|
||||
Cookie cookie = new Cookie(PRESTO_UI_COOKIE, jwt);
|
||||
cookie.setPath("/ui");
|
||||
return cookie;
|
||||
@@ -108,7 +108,7 @@ class SensitiveCookieNotHttpOnly {
|
||||
// BAD - Tests set a sensitive cookie header without the `HttpOnly` flag set using a wrapper method.
|
||||
public void addCookie12(HttpServletRequest request, HttpServletResponse response, String jwt) {
|
||||
Cookie cookie = createAuthenticationCookie(request, jwt);
|
||||
response.addCookie(cookie);
|
||||
response.addCookie(cookie); // $Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests remove a sensitive cookie header without the `HttpOnly` flag set using a wrapper method.
|
||||
@@ -141,7 +141,7 @@ class SensitiveCookieNotHttpOnly {
|
||||
// This example is missed because the `cookie.setHttpOnly` call in `createCookie` is thought to maybe set the HTTP-only flag, and the `cookie`
|
||||
// object flows to this `addCookie` call.
|
||||
public void addCookie15(HttpServletRequest request, HttpServletResponse response, String refreshToken) {
|
||||
response.addCookie(createCookie("refresh_token", refreshToken, false));
|
||||
response.addCookie(createCookie("refresh_token", refreshToken, false)); // $MISSING:Alert
|
||||
}
|
||||
|
||||
// GOOD - CSRF token doesn't need to have the `HttpOnly` flag set.
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql
|
||||
postprocess:
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
1
java/ql/test/query-tests/security/CWE-1004/options
Normal file
1
java/ql/test/query-tests/security/CWE-1004/options
Normal file
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/springframework-5.8.x
|
||||
Reference in New Issue
Block a user