Skip to content

Commit

Permalink
feat(java): add hardcoded secret rule (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet authored Jan 31, 2024
1 parent 035d70d commit 1ef57db
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
109 changes: 109 additions & 0 deletions rules/java/lang/hardcoded_secret.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
patterns:
- pattern: $<...>char[] $<NAME> = $<STRING_LITERAL>.toCharArray()
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- variable: STRING_LITERAL
detection: java_lang_hardcoded_secret_literal
scope: cursor
- pattern: |
class $<...>$<_> $<...> {
$<!>$<...>char[] $<NAME> = $<STRING_LITERAL>.toCharArray()
}
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- variable: STRING_LITERAL
detection: java_lang_hardcoded_secret_literal
scope: cursor
- pattern: $<...>char[] $<NAME> = {};
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- pattern: |
class $<...>$<_> $<...> {
$<!>$<...>char[] $<NAME> = {};
}
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- pattern: $<...>byte[] $<NAME> = new byte[] {};
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- pattern: |
class $<...>$<_> $<...> {
$<!>$<...>byte[] $<NAME> = new byte[] {};
}
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- pattern: $<...>String $<NAME> = $<STRING_LITERAL>;
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- variable: STRING_LITERAL
detection: java_lang_hardcoded_secret_literal
scope: cursor
- pattern: |
class $<...>$<_> $<...> {
$<!>$<...>String $<NAME> = $<STRING_LITERAL>;
}
filters:
- variable: NAME
detection: java_lang_hardcoded_secret_name
scope: cursor_strict
- variable: STRING_LITERAL
detection: java_lang_hardcoded_secret_literal
scope: cursor
auxiliary:
- id: java_lang_hardcoded_secret_name
patterns:
- pattern: $<NAME>;
filters:
- either:
- variable: NAME
regex: (?i)(password|api_?key|api?key|secret)\b
- variable: NAME
regex: (?i)(pass|pwd|psw|cipher|crypt|des|aes|mac|private|secret|sign|cert).*
- id: java_lang_hardcoded_secret_literal
patterns:
- pattern: $<STRING>;
filters:
- variable: STRING
detection: string_literal
scope: cursor_strict
- not:
variable: STRING
string_regex: \A[*•]+\z
- variable: STRING
entropy_greater_than: 3.5
languages:
- java
severity: high
metadata:
description: "Hard-coded secret detected."
remediation_message: |
## Description
Applications should store secret values securely and not as literal values
in the source code.
## Remediations
✅ Retrieve secrets from a secure location at runtime
## Resources
- [OWASP hardcoded passwords](https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password)
- [OWASP secrets management cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html#21-high-availability)
cwe_id:
- 798
id: java_lang_hardcoded_secret
documentation_url: https://docs.bearer.com/reference/rules/java_lang_hardcoded_secret
18 changes: 18 additions & 0 deletions tests/java/lang/hardcoded_secret/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

describe(ruleId, () => {
const invoke = createNewInvoker(ruleId, ruleFile, testBase)

test("hardcoded_secret", () => {
const testCase = "main.java"

const results = invoke(testCase)

expect(results.Missing).toEqual([])
expect(results.Extra).toEqual([])
})
})
46 changes: 46 additions & 0 deletions tests/java/lang/hardcoded_secret/testdata/main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package password;
import java.util.Arrays;

public class ShareTheSecrets {
// ok
private static final byte[] PUBLIC_KEY = new byte[] { 1, 2, 3, 4, 5, 6, 7 };
// bearer:expected java_lang_hardcoded_secret
final String pass2 = "f#a};!y~7VBcu<&F@[%,{b";
// bearer:expected java_lang_hardcoded_secret
private static final byte[] API_KEY = new byte[] { 1, 2, 3, 4, 5, 6, 7 };
// bearer:expected java_lang_hardcoded_secret
private static final String PWD = "hV#;N.F9j}'v5Y-XJc])P*";
// bearer:expected java_lang_hardcoded_secret
private static final char[] password = { 's', 'e', 'c', 'r', 'e', 't', '5' };
// bearer:expected java_lang_hardcoded_secret
public static final String API_KEY = ".uYikE-os3cM23rz.i6Q";

public static void bad() throws Exception {
// bearer:expected java_lang_hardcoded_secret
final String pass2 = "f#a};!y~7VBcu<&F@[%,{b";
// bearer:expected java_lang_hardcoded_secret
char[] ciphertext = "gSbDu-wAE7ZL#[tG4'jfx><HFdVk;5a".toCharArray();
// bearer:expected java_lang_hardcoded_secret
char[] secret = { 's', 'e', 'c', 'r', 'e', 't' };
}

public void alsoBad() throws Exception {
// bearer:expected java_lang_hardcoded_secret
char[] pwd1 = PWD.toCharArray();
// bearer:expected java_lang_hardcoded_secret
public char[] apiKey = {"s", "e", "c", "r", "e", "t"};
// bearer:expected java_lang_hardcoded_secret
char[] pwd = ".uYikE-os3cM23rz.i6Q".toCharArray();
}

public void good() throws Exception {
// test-like data
char[] apiKey = "my-secret-key";
final String API_KEY = "Enter API";
final String pwd = "testing";

// null data
public String password = null;
char[] apiKey =
}
}

0 comments on commit 1ef57db

Please sign in to comment.