mirror of
https://github.com/github/codeql.git
synced 2026-05-14 11:19:27 +02:00
Java: reduce false positives in sensitive-log by expanding FP exclusion regex
The getCommonSensitiveInfoFPRegex() only excluded "null", "tokenizer", and "tokenImage", causing widespread false positives for common non-sensitive variable names containing "token" or "secret". This adds exclusions for three categories: - Pagination/iteration tokens: nextToken (AWS SDK), pageToken (GCP), continuationToken (Azure), etc. - Token metadata: tokenType (OAuth), tokenEndpoint (OIDC), tokenCount, tokenIndex, tokenLength, tokenUrl, etc. - Secret metadata: secretName (K8s/AWS), secretId (Azure), secretVersion, secretArn, secretPath, etc. All truly sensitive variable names (accessToken, clientSecret, secretKey, refreshToken, etc.) remain correctly flagged.
This commit is contained in:
@@ -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:67:21:67:43 | ... + ... | Test.java:67:33:67:43 | accessToken : String | Test.java:67:21:67:43 | ... + ... | This $@ is written to a log file. | Test.java:67:33:67:43 | accessToken | potentially sensitive information |
|
||||
| Test.java:68:21:68:45 | ... + ... | Test.java:68:34:68:45 | clientSecret : String | Test.java:68:21:68:45 | ... + ... | This $@ is written to a log file. | Test.java:68:34:68:45 | clientSecret | potentially sensitive information |
|
||||
| Test.java:69:21:69:42 | ... + ... | Test.java:69:34:69:42 | apiSecret : String | Test.java:69:21:69:42 | ... + ... | This $@ is written to a log file. | Test.java:69:34:69:42 | apiSecret | potentially sensitive information |
|
||||
| Test.java:70:21:70:44 | ... + ... | Test.java:70:33:70:44 | sessionToken : String | Test.java:70:21:70:44 | ... + ... | This $@ is written to a log file. | Test.java:70:33:70:44 | sessionToken | potentially sensitive information |
|
||||
| Test.java:71:21:71:43 | ... + ... | Test.java:71:33:71:43 | bearerToken : String | Test.java:71:21:71:43 | ... + ... | This $@ is written to a log file. | Test.java:71:33:71:43 | bearerToken | potentially sensitive information |
|
||||
| Test.java:72:21:72:39 | ... + ... | Test.java:72:31:72:39 | secretKey : String | Test.java:72:21:72:39 | ... + ... | This $@ is written to a log file. | Test.java:72:31:72:39 | secretKey | potentially sensitive information |
|
||||
| Test.java:73:21:73:44 | ... + ... | Test.java:73:33:73:44 | refreshToken : String | Test.java:73:21:73:44 | ... + ... | This $@ is written to a log file. | Test.java:73:33:73:44 | refreshToken | potentially sensitive information |
|
||||
| Test.java:74:21:74:43 | ... + ... | Test.java:74:33:74:43 | secretValue : String | Test.java:74:21:74:43 | ... + ... | This $@ is written to a log file. | Test.java:74:33:74: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:67:33:67:43 | accessToken : String | Test.java:67:21:67:43 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:68:34:68:45 | clientSecret : String | Test.java:68:21:68:45 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:69:34:69:42 | apiSecret : String | Test.java:69:21:69:42 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:70:33:70:44 | sessionToken : String | Test.java:70:21:70:44 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:71:33:71:43 | bearerToken : String | Test.java:71:21:71:43 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:72:31:72:39 | secretKey : String | Test.java:72:21:72:39 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:73:33:73:44 | refreshToken : String | Test.java:73:21:73:44 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:74:33:74:43 | secretValue : String | Test.java:74:21:74: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:67:21:67:43 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:67:33:67:43 | accessToken : String | semmle.label | accessToken : String |
|
||||
| Test.java:68:21:68:45 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:68:34:68:45 | clientSecret : String | semmle.label | clientSecret : String |
|
||||
| Test.java:69:21:69:42 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:69:34:69:42 | apiSecret : String | semmle.label | apiSecret : String |
|
||||
| Test.java:70:21:70:44 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:70:33:70:44 | sessionToken : String | semmle.label | sessionToken : String |
|
||||
| Test.java:71:21:71:43 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:71:33:71:43 | bearerToken : String | semmle.label | bearerToken : String |
|
||||
| Test.java:72:21:72:39 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:72:31:72:39 | secretKey : String | semmle.label | secretKey : String |
|
||||
| Test.java:73:21:73:44 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:73:33:73:44 | refreshToken : String | semmle.label | refreshToken : String |
|
||||
| Test.java:74:21:74:43 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:74:33:74:43 | secretValue : String | semmle.label | secretValue : String |
|
||||
subpaths
|
||||
|
||||
@@ -21,4 +21,56 @@ 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 secretQuestion,
|
||||
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("question: " + secretQuestion); // 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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user