diff --git a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll index 1ee03e2d4b5..e2cbba1ee79 100644 --- a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll @@ -62,24 +62,27 @@ module HardcodedCryptographicValue { abstract class Barrier extends DataFlow::Node { } /** - * A literal, considered as a flow source. + * Holds if `e` is a literal or a combination of literals that is constant. */ - private class LiteralSource extends Source { - LiteralSource() { this.asExpr() instanceof LiteralExpr } + private predicate isConstant(Expr e) { + e instanceof LiteralExpr // e.g. `0` + or + e.(ArrayListExpr).getExpr(_) instanceof LiteralExpr // e.g. `[0, 0, 0, 0]` + or + e.(ArrayRepeatExpr).getRepeatOperand() instanceof LiteralExpr // e.g. `[0; 10]` + or + e instanceof ConstAccess // e.g. `u64::MAX` + or + // e.g. `1 << 4` + isConstant(e.(BinaryExpr).getLhs()) and + isConstant(e.(BinaryExpr).getRhs()) } /** - * An array initialized from a list of literals, considered as a single flow source. For example: - * ``` - * [0, 0, 0, 0] - * [0; 10] - * ``` + * A constant, considered as a flow source. */ - private class ArrayListSource extends Source { - ArrayListSource() { - this.asExpr().(ArrayListExpr).getExpr(_) instanceof LiteralExpr or - this.asExpr().(ArrayRepeatExpr).getRepeatOperand() instanceof LiteralExpr - } + private class ConstantSource extends Source { + ConstantSource() { isConstant(this.asExpr()) } } /** @@ -165,9 +168,9 @@ module HardcodedCryptographicValue { private class ArithmeticOperationBarrier extends Barrier { ArithmeticOperationBarrier() { // binary operations (e.g. `a + b`, `a ^ b`) - this.asExpr() instanceof BinaryArithmeticOperation + this.asExpr() = any(BinaryArithmeticOperation a).getAnOperand() or - this.asExpr() instanceof BinaryBitwiseOperation + this.asExpr() = any(BinaryBitwiseOperation a).getAnOperand() or // compound assignments (e.g. `a += b`, `a ^= b`) this.asExpr() = any(AssignArithmeticOperation a).getAnOperand() diff --git a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected index c6c6ce8a662..e70bbe23763 100644 --- a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected +++ b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected @@ -15,6 +15,9 @@ | test_heuristic.rs:64:20:64:27 | [0u8; 16] | test_heuristic.rs:64:20:64:27 | [0u8; 16] | test_heuristic.rs:64:19:64:27 | &... | This hard-coded value is used as $@. | test_heuristic.rs:64:19:64:27 | &... | a nonce | | test_heuristic.rs:65:31:65:38 | [0u8; 16] | test_heuristic.rs:65:31:65:38 | [0u8; 16] | test_heuristic.rs:65:30:65:38 | &... | This hard-coded value is used as $@. | test_heuristic.rs:65:30:65:38 | &... | a salt | | test_heuristic.rs:67:22:67:22 | 0 | test_heuristic.rs:67:22:67:22 | 0 | test_heuristic.rs:67:22:67:22 | 0 | This hard-coded value is used as $@. | test_heuristic.rs:67:22:67:22 | 0 | a salt | +| test_heuristic.rs:71:22:71:27 | ... << ... | test_heuristic.rs:71:22:71:27 | ... << ... | test_heuristic.rs:71:22:71:27 | ... << ... | This hard-coded value is used as $@. | test_heuristic.rs:71:22:71:27 | ... << ... | a salt | +| test_heuristic.rs:72:22:72:29 | ...::MAX | test_heuristic.rs:72:22:72:29 | ...::MAX | test_heuristic.rs:72:22:72:29 | ...::MAX | This hard-coded value is used as $@. | test_heuristic.rs:72:22:72:29 | ...::MAX | a salt | +| test_heuristic.rs:73:22:73:33 | ... / ... | test_heuristic.rs:73:22:73:33 | ... / ... | test_heuristic.rs:73:22:73:33 | ... / ... | This hard-coded value is used as $@. | test_heuristic.rs:73:22:73:33 | ... / ... | a salt | edges | test_cipher.rs:18:9:18:14 | const1 [&ref] | test_cipher.rs:19:73:19:78 | const1 [&ref] | provenance | | | test_cipher.rs:18:28:18:36 | &... [&ref] | test_cipher.rs:18:9:18:14 | const1 [&ref] | provenance | | @@ -164,4 +167,7 @@ nodes | test_heuristic.rs:65:30:65:38 | &... | semmle.label | &... | | test_heuristic.rs:65:31:65:38 | [0u8; 16] | semmle.label | [0u8; 16] | | test_heuristic.rs:67:22:67:22 | 0 | semmle.label | 0 | +| test_heuristic.rs:71:22:71:27 | ... << ... | semmle.label | ... << ... | +| test_heuristic.rs:72:22:72:29 | ...::MAX | semmle.label | ...::MAX | +| test_heuristic.rs:73:22:73:33 | ... / ... | semmle.label | ... / ... | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs b/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs index 9f5d458b416..bfc07e80f16 100644 --- a/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs +++ b/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs @@ -68,9 +68,9 @@ fn test(var_string: &str, var_data: &[u8;16], var_u64: u64) { mc2.set_salt_u64(var_u64); mc2.set_salt_u64(var_u64 + 1); mc2.set_salt_u64((var_u64 << 32) ^ (var_u64 & 0xFFFFFFFF)); - mc2.set_salt_u64(1 << 4); // $ MISSING: Alert[rust/hard-coded-cryptographic-value] - mc2.set_salt_u64(u64::MAX); // $ MISSING: Alert[rust/hard-coded-cryptographic-value] - mc2.set_salt_u64(u64::MAX / 4); // $ MISSING: Alert[rust/hard-coded-cryptographic-value] + mc2.set_salt_u64(1 << 4); // $ Alert[rust/hard-coded-cryptographic-value] + mc2.set_salt_u64(u64::MAX); // $ Alert[rust/hard-coded-cryptographic-value] + mc2.set_salt_u64(u64::MAX / 4); // $ Alert[rust/hard-coded-cryptographic-value] let mut key1 = "foo".to_string(); // $ MISSING: Alert[rust/hard-coded-cryptographic-value] key1 += "bar"; // $ MISSING: Alert[rust/hard-coded-cryptographic-value]