Merge branch 'github:main' into fix/path-injection-read-subkind

This commit is contained in:
Kaixuan Li
2026-04-21 22:59:53 +10:00
committed by GitHub
197 changed files with 1499 additions and 623 deletions

View File

@@ -1,3 +1,9 @@
## 9.0.4
### Minor Analysis Improvements
* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the Woodstox StAX library when `com.ctc.wstx.stax.WstxInputFactory` or `org.codehaus.stax2.XMLInputFactory2` are used directly.
## 9.0.3
### Minor Analysis Improvements

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Java and Kotlin](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/).

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `java/sensitive-log` query now excludes additional common variable naming patterns that do not hold sensitive data, reducing false positives. This includes pagination/iteration tokens (`nextToken`, `pageToken`, `continuationToken`), token metadata (`tokenType`, `tokenEndpoint`, `tokenCount`), and secret metadata (`secretName`, `secretId`, `secretVersion`).

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 9.0.4
### Minor Analysis Improvements
* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the Woodstox StAX library when `com.ctc.wstx.stax.WstxInputFactory` or `org.codehaus.stax2.XMLInputFactory2` are used directly.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 9.0.3
lastReleaseVersion: 9.0.4

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 9.0.4-dev
version: 9.0.5-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -40,14 +40,26 @@ string getCommonSensitiveInfoRegex() {
/**
* Gets a regular expression for matching common names of variables that
* indicate the value being held does not contains sensitive information,
* indicate the value being held does not contain sensitive information,
* but is a false positive for `getCommonSensitiveInfoRegex`.
*
* - "tokenizer" is often used for java.util.StringTokenizer.
* - "tokenImage" appears in parser code generated by JavaCC.
* - Pagination/iteration tokens: "nextToken" (AWS SDK), "pageToken" (GCP), etc.
* - Token metadata: "tokenType" (OAuth), "tokenEndpoint" (OIDC), "tokenCount", etc.
* - Secret metadata: "secretName" (K8s/AWS), "secretId" (Azure), "secretVersion", etc.
*/
string getCommonSensitiveInfoFPRegex() {
result = "(?i).*(null|tokenizer).*" or result = "tokenImage"
result =
[
"(?i).*(null|tokenizer).*", "tokenImage",
// Pagination/iteration tokens (e.g., AWS SDK pagination cursors, parser tokens)
"(?i).*(next|previous|current|page|continuation|cursor)tokens?.*",
// Token metadata/infrastructure (token followed by a non-value descriptor)
"(?i).*tokens?(type|kind|count|index|position|length|offset|endpoint|url|uri|bucket|rate|delimiter|separator|format|number|name|id|prefix|suffix|pattern|class|style).*",
// Secret metadata (secret followed by a non-value descriptor)
"(?i).*secrets?(name|id|version|ref|arn|path|type|label|description|manager|client|provider|store|factory|properties).*"
]
}
/** An expression that might contain sensitive data. */

View File

@@ -1,3 +1,7 @@
## 1.11.1
No user-facing changes.
## 1.11.0
### Query Metadata Changes

View File

@@ -0,0 +1,3 @@
## 1.11.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.11.0
lastReleaseVersion: 1.11.1

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 1.11.1-dev
version: 1.11.2-dev
groups:
- java
- queries

View File

@@ -3,6 +3,14 @@
| Test.java:12:22:12:52 | ... + ... | Test.java:12:44:12:52 | authToken : String | Test.java:12:22:12:52 | ... + ... | This $@ is written to a log file. | Test.java:12:44:12:52 | authToken | potentially sensitive information |
| Test.java:21:22:21:75 | ... + ... | Test.java:21:44:21:52 | authToken : String | Test.java:21:22:21:75 | ... + ... | This $@ is written to a log file. | Test.java:21:44:21:52 | authToken | potentially sensitive information |
| Test.java:22:22:22:75 | ... + ... | Test.java:22:44:22:52 | authToken : String | Test.java:22:22:22:75 | ... + ... | This $@ is written to a log file. | Test.java:22:44:22:52 | authToken | potentially sensitive information |
| Test.java:66:21:66:43 | ... + ... | Test.java:66:33:66:43 | accessToken : String | Test.java:66:21:66:43 | ... + ... | This $@ is written to a log file. | Test.java:66:33:66:43 | accessToken | potentially sensitive information |
| Test.java:67:21:67:45 | ... + ... | Test.java:67:34:67:45 | clientSecret : String | Test.java:67:21:67:45 | ... + ... | This $@ is written to a log file. | Test.java:67:34:67:45 | clientSecret | potentially sensitive information |
| Test.java:68:21:68:42 | ... + ... | Test.java:68:34:68:42 | apiSecret : String | Test.java:68:21:68:42 | ... + ... | This $@ is written to a log file. | Test.java:68:34:68:42 | apiSecret | potentially sensitive information |
| Test.java:69:21:69:44 | ... + ... | Test.java:69:33:69:44 | sessionToken : String | Test.java:69:21:69:44 | ... + ... | This $@ is written to a log file. | Test.java:69:33:69:44 | sessionToken | potentially sensitive information |
| Test.java:70:21:70:43 | ... + ... | Test.java:70:33:70:43 | bearerToken : String | Test.java:70:21:70:43 | ... + ... | This $@ is written to a log file. | Test.java:70:33:70:43 | bearerToken | potentially sensitive information |
| Test.java:71:21:71:39 | ... + ... | Test.java:71:31:71:39 | secretKey : String | Test.java:71:21:71:39 | ... + ... | This $@ is written to a log file. | Test.java:71:31:71:39 | secretKey | potentially sensitive information |
| Test.java:72:21:72:44 | ... + ... | Test.java:72:33:72:44 | refreshToken : String | Test.java:72:21:72:44 | ... + ... | This $@ is written to a log file. | Test.java:72:33:72:44 | refreshToken | potentially sensitive information |
| Test.java:73:21:73:43 | ... + ... | Test.java:73:33:73:43 | secretValue : String | Test.java:73:21:73:43 | ... + ... | This $@ is written to a log file. | Test.java:73:33:73:43 | secretValue | potentially sensitive information |
edges
| Test.java:11:46:11:53 | password : String | Test.java:11:21:11:53 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:12:44:12:52 | authToken : String | Test.java:12:22:12:52 | ... + ... | provenance | Sink:MaD:1 |
@@ -10,6 +18,14 @@ edges
| Test.java:21:44:21:67 | substring(...) : String | Test.java:21:22:21:75 | ... + ... | provenance | Sink:MaD:1 |
| Test.java:22:44:22:52 | authToken : String | Test.java:22:44:22:67 | substring(...) : String | provenance | MaD:3 |
| Test.java:22:44:22:67 | substring(...) : String | Test.java:22:22:22:75 | ... + ... | provenance | Sink:MaD:1 |
| Test.java:66:33:66:43 | accessToken : String | Test.java:66:21:66:43 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:67:34:67:45 | clientSecret : String | Test.java:67:21:67:45 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:68:34:68:42 | apiSecret : String | Test.java:68:21:68:42 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:69:33:69:44 | sessionToken : String | Test.java:69:21:69:44 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:70:33:70:43 | bearerToken : String | Test.java:70:21:70:43 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:71:31:71:39 | secretKey : String | Test.java:71:21:71:39 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:72:33:72:44 | refreshToken : String | Test.java:72:21:72:44 | ... + ... | provenance | Sink:MaD:2 |
| Test.java:73:33:73:43 | secretValue : String | Test.java:73:21:73:43 | ... + ... | provenance | Sink:MaD:2 |
models
| 1 | Sink: org.apache.logging.log4j; Logger; true; error; (String); ; Argument[0]; log-injection; manual |
| 2 | Sink: org.apache.logging.log4j; Logger; true; info; (String); ; Argument[0]; log-injection; manual |
@@ -25,4 +41,20 @@ nodes
| Test.java:22:22:22:75 | ... + ... | semmle.label | ... + ... |
| Test.java:22:44:22:52 | authToken : String | semmle.label | authToken : String |
| Test.java:22:44:22:67 | substring(...) : String | semmle.label | substring(...) : String |
| Test.java:66:21:66:43 | ... + ... | semmle.label | ... + ... |
| Test.java:66:33:66:43 | accessToken : String | semmle.label | accessToken : String |
| Test.java:67:21:67:45 | ... + ... | semmle.label | ... + ... |
| Test.java:67:34:67:45 | clientSecret : String | semmle.label | clientSecret : String |
| Test.java:68:21:68:42 | ... + ... | semmle.label | ... + ... |
| Test.java:68:34:68:42 | apiSecret : String | semmle.label | apiSecret : String |
| Test.java:69:21:69:44 | ... + ... | semmle.label | ... + ... |
| Test.java:69:33:69:44 | sessionToken : String | semmle.label | sessionToken : String |
| Test.java:70:21:70:43 | ... + ... | semmle.label | ... + ... |
| Test.java:70:33:70:43 | bearerToken : String | semmle.label | bearerToken : String |
| Test.java:71:21:71:39 | ... + ... | semmle.label | ... + ... |
| Test.java:71:31:71:39 | secretKey : String | semmle.label | secretKey : String |
| Test.java:72:21:72:44 | ... + ... | semmle.label | ... + ... |
| Test.java:72:33:72:44 | refreshToken : String | semmle.label | refreshToken : String |
| Test.java:73:21:73:43 | ... + ... | semmle.label | ... + ... |
| Test.java:73:33:73:43 | secretValue : String | semmle.label | secretValue : String |
subpaths

View File

@@ -21,4 +21,55 @@ class Test {
logger.error("Auth failed for: " + authToken.substring(1,5) + "..."); // $ Alert
logger.error("Auth failed for: " + authToken.substring(0,8) + "..."); // $ Alert
}
// Tests for false positive exclusions: variables with "token" or "secret" in the name
// that do not hold sensitive data.
void testFalsePositiveExclusions(
String nextToken, String pageToken, String continuationToken, String cursorToken,
String tokenType, String tokenEndpoint, String tokenCount, String tokenUrl,
String tokenIndex, String tokenLength, String tokenName, String tokenId,
String secretName, String secretId, String secretVersion, String secretArn,
String secretPath, String secretType,
String secretManager, String secretProperties
) {
Logger logger = null;
// Pagination/iteration tokens (e.g., AWS SDK, GCP, Azure pagination cursors)
logger.info("cursor: " + nextToken); // Safe
logger.info("cursor: " + pageToken); // Safe
logger.info("cursor: " + continuationToken); // Safe
logger.info("cursor: " + cursorToken); // Safe
// Token metadata (e.g., OAuth token type, OIDC discovery endpoint)
logger.info("type: " + tokenType); // Safe
logger.info("endpoint: " + tokenEndpoint); // Safe
logger.info("count: " + tokenCount); // Safe
logger.info("url: " + tokenUrl); // Safe
logger.info("index: " + tokenIndex); // Safe
logger.info("length: " + tokenLength); // Safe
logger.info("name: " + tokenName); // Safe
logger.info("id: " + tokenId); // Safe
// Secret metadata (e.g., K8s secret name, AWS Secrets Manager identifiers)
logger.info("name: " + secretName); // Safe
logger.info("id: " + secretId); // Safe
logger.info("version: " + secretVersion); // Safe
logger.info("arn: " + secretArn); // Safe
logger.info("path: " + secretPath); // Safe
logger.info("type: " + secretType); // Safe
logger.info("manager: " + secretManager); // Safe
logger.info("properties: " + secretProperties); // Safe
}
// These should still be flagged as sensitive
void testTruePositives(String accessToken, String clientSecret, String apiSecret,
String sessionToken, String bearerToken, String secretKey,
String refreshToken, String secretValue) {
Logger logger = null;
logger.info("token: " + accessToken); // $ Alert
logger.info("secret: " + clientSecret); // $ Alert
logger.info("secret: " + apiSecret); // $ Alert
logger.info("token: " + sessionToken); // $ Alert
logger.info("token: " + bearerToken); // $ Alert
logger.info("key: " + secretKey); // $ Alert
logger.info("token: " + refreshToken); // $ Alert
logger.info("value: " + secretValue); // $ Alert
}
}