Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,22 @@ module HardcodedCryptographicValue {
abstract class Barrier extends DataFlow::Node { }

/**
* Holds if `e` is a literal or a combination of literals that is constant.
* Holds if `e` is a literal or an expression that contains a constant. For example:
* ```
* ["hello", "world", s]
* ```
*/
private predicate isConstant(Expr e) {
private predicate hasConstant(Expr e) {
e instanceof LiteralExpr // e.g. `0`
or
forex(Expr elem | elem = e.(ArrayListExpr).getExpr(_) | isConstant(elem)) // e.g. `[0, 0, 0, 0]`
exists(Expr elem | elem = e.(ArrayListExpr).getExpr(_) | hasConstant(elem)) // e.g. `[0, 0, 0, 0]`
or
isConstant(e.(ArrayRepeatExpr).getRepeatOperand()) // e.g. `[0; 10]`
hasConstant(e.(ArrayRepeatExpr).getRepeatOperand()) // e.g. `[0; 10]`
or
// a match expression with one or more constant arms; taint would reach here
// anyway, but we make it a source to avoid reporting many similar results
// on each match arm.
hasConstant(e.(MatchExpr).getMatchArmList().getAnArm().getExpr())
or
// e.g. `const MY_CONST: u64 = ...`
// the constant initializer / body is the preferred source location for flow paths, when available.
Expand All @@ -81,15 +89,15 @@ module HardcodedCryptographicValue {
not exists(e.(ConstAccess).getConst().getBody())
or
// e.g. `1 << 4`
isConstant(e.(BinaryExpr).getLhs()) and
isConstant(e.(BinaryExpr).getRhs())
hasConstant(e.(BinaryExpr).getLhs()) and
hasConstant(e.(BinaryExpr).getRhs())
}

/**
* A constant, considered as a flow source.
*/
private class ConstantSource extends Source {
ConstantSource() { isConstant(this.asExpr()) }
ConstantSource() { hasConstant(this.asExpr()) }
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The `rust/hard-coded-cryptographic-value` query has been adjusted to produce
fewer results in certain situations where many results were being produced with very similar source locations.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
| test_cipher.rs:73:19:73:26 | [0u8; 32] | test_cipher.rs:73:19:73:26 | [0u8; 32] | test_cipher.rs:74:46:74:51 | const2 | This hard-coded value is used as $@. | test_cipher.rs:74:46:74:51 | const2 | a key |
| test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:18:26:18:32 | &array1 | This hard-coded value is used as $@. | test_cookie.rs:18:26:18:32 | &array1 | a key |
| test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:22:26:22:32 | &array2 | This hard-coded value is used as $@. | test_cookie.rs:22:26:22:32 | &array2 | a key |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:42:34:42:39 | array2 | This hard-coded value is used as $@. | test_cookie.rs:42:34:42:39 | array2 | a key |
| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:53:34:53:39 | array3 | This hard-coded value is used as $@. | test_cookie.rs:53:34:53:39 | array3 | a key |
| test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:30:26:30:40 | str3.as_bytes() | This hard-coded value is used as $@. | test_cookie.rs:30:26:30:40 | str3.as_bytes() | a key |
| test_cookie.rs:33:27:37:5 | [...] | test_cookie.rs:33:27:37:5 | [...] | test_cookie.rs:38:26:38:32 | &array4 | This hard-coded value is used as $@. | test_cookie.rs:38:26:38:32 | &array4 | a key |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:58:34:58:39 | array2 | This hard-coded value is used as $@. | test_cookie.rs:58:34:58:39 | array2 | a key |
| test_cookie.rs:65:23:65:25 | 0u8 | test_cookie.rs:65:23:65:25 | 0u8 | test_cookie.rs:69:34:69:39 | array3 | This hard-coded value is used as $@. | test_cookie.rs:69:34:69:39 | array3 | a key |
| test_heuristic.rs:38:25:38:30 | 0xFFFF | test_heuristic.rs:38:25:38:30 | 0xFFFF | test_heuristic.rs:81:22:81:31 | MY_CONST_1 | This hard-coded value is used as $@. | test_heuristic.rs:81:22:81:31 | MY_CONST_1 | a salt |
| test_heuristic.rs:39:25:39:59 | ... as u64 | test_heuristic.rs:39:25:39:59 | ... as u64 | test_heuristic.rs:82:22:82:31 | MY_CONST_2 | This hard-coded value is used as $@. | test_heuristic.rs:82:22:82:31 | MY_CONST_2 | a salt |
| test_heuristic.rs:40:27:40:32 | 0xFFFF | test_heuristic.rs:40:27:40:32 | 0xFFFF | test_heuristic.rs:83:22:83:32 | MY_STATIC_3 | This hard-coded value is used as $@. | test_heuristic.rs:83:22:83:32 | MY_STATIC_3 | a salt |
Expand All @@ -28,31 +30,31 @@ edges
| test_cipher.rs:18:28:18:36 | &... [&ref] | test_cipher.rs:18:9:18:14 | const1 [&ref] | provenance | |
| test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:18:28:18:36 | &... [&ref] | provenance | |
| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) | provenance | Sink:MaD:2 |
| test_cipher.rs:19:73:19:78 | const1 [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | provenance | MaD:13 |
| test_cipher.rs:19:73:19:78 | const1 [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | provenance | MaD:14 |
| test_cipher.rs:25:9:25:14 | const4 [&ref] | test_cipher.rs:26:66:26:71 | const4 [&ref] | provenance | |
| test_cipher.rs:25:28:25:36 | &... [&ref] | test_cipher.rs:25:9:25:14 | const4 [&ref] | provenance | |
| test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:25:28:25:36 | &... [&ref] | provenance | |
| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) | provenance | Sink:MaD:3 |
| test_cipher.rs:26:66:26:71 | const4 [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | provenance | MaD:13 |
| test_cipher.rs:26:66:26:71 | const4 [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | provenance | MaD:14 |
| test_cipher.rs:29:9:29:14 | const5 [&ref] | test_cipher.rs:30:95:30:100 | const5 [&ref] | provenance | |
| test_cipher.rs:29:28:29:36 | &... [&ref] | test_cipher.rs:29:9:29:14 | const5 [&ref] | provenance | |
| test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:29:28:29:36 | &... [&ref] | provenance | |
| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) | provenance | Sink:MaD:4 |
| test_cipher.rs:30:95:30:100 | const5 [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | provenance | MaD:13 |
| test_cipher.rs:30:95:30:100 | const5 [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | provenance | MaD:14 |
| test_cipher.rs:37:9:37:14 | const7 | test_cipher.rs:38:74:38:79 | const7 | provenance | |
| test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:9:37:14 | const7 | provenance | |
| test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) | provenance | Sink:MaD:2 |
| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:13 |
| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:14 |
| test_cipher.rs:38:74:38:79 | const7 | test_cipher.rs:38:73:38:79 | &const7 [&ref] | provenance | |
| test_cipher.rs:41:9:41:14 | const8 [&ref] | test_cipher.rs:42:73:42:78 | const8 [&ref] | provenance | |
| test_cipher.rs:41:28:41:76 | &... [&ref] | test_cipher.rs:41:9:41:14 | const8 [&ref] | provenance | |
| test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:28:41:76 | &... [&ref] | provenance | |
| test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) | provenance | Sink:MaD:2 |
| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:13 |
| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:14 |
| test_cipher.rs:50:9:50:15 | const10 [element] | test_cipher.rs:51:75:51:81 | const10 [element] | provenance | |
| test_cipher.rs:50:37:50:54 | ...::zeroed(...) | test_cipher.rs:50:9:50:15 | const10 [element] | provenance | Src:MaD:7 |
| test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) | provenance | Sink:MaD:2 Sink:MaD:2 |
| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:13 |
| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:14 |
| test_cipher.rs:51:75:51:81 | const10 [element] | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | provenance | |
| test_cipher.rs:73:9:73:14 | const2 [&ref] | test_cipher.rs:74:46:74:51 | const2 | provenance | Sink:MaD:6 |
| test_cipher.rs:73:18:73:26 | &... [&ref] | test_cipher.rs:73:9:73:14 | const2 [&ref] | provenance | |
Expand All @@ -65,16 +67,24 @@ edges
| test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:9:21:14 | array2 | provenance | |
| test_cookie.rs:22:26:22:32 | &array2 [&ref] | test_cookie.rs:22:26:22:32 | &array2 | provenance | Sink:MaD:5 |
| test_cookie.rs:22:27:22:32 | array2 | test_cookie.rs:22:26:22:32 | &array2 [&ref] | provenance | |
| test_cookie.rs:38:9:38:14 | array2 | test_cookie.rs:42:34:42:39 | array2 | provenance | Sink:MaD:1 |
| test_cookie.rs:38:18:38:37 | ...::from(...) | test_cookie.rs:38:9:38:14 | array2 | provenance | |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:8 |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:9 |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:10 |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:11 |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:12 |
| test_cookie.rs:49:9:49:14 | array3 [element] | test_cookie.rs:53:34:53:39 | array3 | provenance | Sink:MaD:1 |
| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:14 |
| test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | test_cookie.rs:49:9:49:14 | array3 [element] | provenance | |
| test_cookie.rs:25:9:25:12 | str3 | test_cookie.rs:30:26:30:29 | str3 | provenance | |
| test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:25:9:25:12 | str3 | provenance | |
| test_cookie.rs:30:26:30:29 | str3 | test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | provenance | MaD:13 |
| test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | test_cookie.rs:30:26:30:40 | str3.as_bytes() | provenance | Sink:MaD:5 |
| test_cookie.rs:33:9:33:14 | array4 | test_cookie.rs:38:27:38:32 | array4 | provenance | |
| test_cookie.rs:33:27:37:5 | [...] | test_cookie.rs:33:9:33:14 | array4 | provenance | |
| test_cookie.rs:38:26:38:32 | &array4 [&ref] | test_cookie.rs:38:26:38:32 | &array4 | provenance | Sink:MaD:5 |
| test_cookie.rs:38:27:38:32 | array4 | test_cookie.rs:38:26:38:32 | &array4 [&ref] | provenance | |
| test_cookie.rs:54:9:54:14 | array2 | test_cookie.rs:58:34:58:39 | array2 | provenance | Sink:MaD:1 |
| test_cookie.rs:54:18:54:37 | ...::from(...) | test_cookie.rs:54:9:54:14 | array2 | provenance | |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:18:54:37 | ...::from(...) | provenance | MaD:8 |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:18:54:37 | ...::from(...) | provenance | MaD:9 |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:18:54:37 | ...::from(...) | provenance | MaD:10 |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:18:54:37 | ...::from(...) | provenance | MaD:11 |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:18:54:37 | ...::from(...) | provenance | MaD:12 |
| test_cookie.rs:65:9:65:14 | array3 [element] | test_cookie.rs:69:34:69:39 | array3 | provenance | Sink:MaD:1 |
| test_cookie.rs:65:23:65:25 | 0u8 | test_cookie.rs:65:23:65:29 | ...::from_elem(...) [element] | provenance | MaD:15 |
| test_cookie.rs:65:23:65:29 | ...::from_elem(...) [element] | test_cookie.rs:65:9:65:14 | array3 [element] | provenance | |
| test_heuristic.rs:38:25:38:30 | 0xFFFF | test_heuristic.rs:81:22:81:31 | MY_CONST_1 | provenance | |
| test_heuristic.rs:39:25:39:59 | ... as u64 | test_heuristic.rs:82:22:82:31 | MY_CONST_2 | provenance | |
| test_heuristic.rs:39:62:40:33 | static MY_STATIC_3 | test_heuristic.rs:83:22:83:32 | MY_STATIC_3 | provenance | |
Expand All @@ -99,8 +109,9 @@ models
| 10 | Summary: <alloc::vec::Vec as core::convert::From>::from; Argument[0].Field[alloc::collections::binary_heap::BinaryHeap::data]; ReturnValue; value |
| 11 | Summary: <alloc::vec::Vec as core::convert::From>::from; Argument[0].Field[alloc::string::String::vec]; ReturnValue; value |
| 12 | Summary: <alloc::vec::Vec as core::convert::From>::from; Argument[0]; ReturnValue; taint |
| 13 | Summary: <generic_array::GenericArray>::from_slice; Argument[0].Reference; ReturnValue.Reference; value |
| 14 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value |
| 13 | Summary: <core::str>::as_bytes; Argument[self].Reference; ReturnValue.Reference; taint |
| 14 | Summary: <generic_array::GenericArray>::from_slice; Argument[0].Reference; ReturnValue.Reference; value |
| 15 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value |
nodes
| test_cipher.rs:18:9:18:14 | const1 [&ref] | semmle.label | const1 [&ref] |
| test_cipher.rs:18:28:18:36 | &... [&ref] | semmle.label | &... [&ref] |
Expand Down Expand Up @@ -152,14 +163,24 @@ nodes
| test_cookie.rs:22:26:22:32 | &array2 | semmle.label | &array2 |
| test_cookie.rs:22:26:22:32 | &array2 [&ref] | semmle.label | &array2 [&ref] |
| test_cookie.rs:22:27:22:32 | array2 | semmle.label | array2 |
| test_cookie.rs:38:9:38:14 | array2 | semmle.label | array2 |
| test_cookie.rs:38:18:38:37 | ...::from(...) | semmle.label | ...::from(...) |
| test_cookie.rs:38:28:38:36 | [0u8; 64] | semmle.label | [0u8; 64] |
| test_cookie.rs:42:34:42:39 | array2 | semmle.label | array2 |
| test_cookie.rs:49:9:49:14 | array3 [element] | semmle.label | array3 [element] |
| test_cookie.rs:49:23:49:25 | 0u8 | semmle.label | 0u8 |
| test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | semmle.label | ...::from_elem(...) [element] |
| test_cookie.rs:53:34:53:39 | array3 | semmle.label | array3 |
| test_cookie.rs:25:9:25:12 | str3 | semmle.label | str3 |
| test_cookie.rs:25:16:29:5 | match ... { ... } | semmle.label | match ... { ... } |
| test_cookie.rs:30:26:30:29 | str3 | semmle.label | str3 |
| test_cookie.rs:30:26:30:40 | str3.as_bytes() | semmle.label | str3.as_bytes() |
| test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | semmle.label | str3.as_bytes() [&ref] |
| test_cookie.rs:33:9:33:14 | array4 | semmle.label | array4 |
| test_cookie.rs:33:27:37:5 | [...] | semmle.label | [...] |
| test_cookie.rs:38:26:38:32 | &array4 | semmle.label | &array4 |
| test_cookie.rs:38:26:38:32 | &array4 [&ref] | semmle.label | &array4 [&ref] |
| test_cookie.rs:38:27:38:32 | array4 | semmle.label | array4 |
| test_cookie.rs:54:9:54:14 | array2 | semmle.label | array2 |
| test_cookie.rs:54:18:54:37 | ...::from(...) | semmle.label | ...::from(...) |
| test_cookie.rs:54:28:54:36 | [0u8; 64] | semmle.label | [0u8; 64] |
| test_cookie.rs:58:34:58:39 | array2 | semmle.label | array2 |
| test_cookie.rs:65:9:65:14 | array3 [element] | semmle.label | array3 [element] |
| test_cookie.rs:65:23:65:25 | 0u8 | semmle.label | 0u8 |
| test_cookie.rs:65:23:65:29 | ...::from_elem(...) [element] | semmle.label | ...::from_elem(...) [element] |
| test_cookie.rs:69:34:69:39 | array3 | semmle.label | array3 |
| test_heuristic.rs:38:25:38:30 | 0xFFFF | semmle.label | 0xFFFF |
| test_heuristic.rs:39:25:39:59 | ... as u64 | semmle.label | ... as u64 |
| test_heuristic.rs:39:62:40:33 | static MY_STATIC_3 | semmle.label | static MY_STATIC_3 |
Expand Down
18 changes: 17 additions & 1 deletion rust/ql/test/query-tests/security/CWE-798/test_cookie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use cookie::{CookieJar, SignedJar, PrivateJar, Key};

// --- tests ---

fn test_cookie_jar(array_var: &[u8]) {
fn test_cookie_jar(array_var: &[u8], val: u64) {
let mut jar = CookieJar::new();

let key_generate = Key::generate(); // good
Expand All @@ -21,6 +21,22 @@ fn test_cookie_jar(array_var: &[u8]) {
let array2: [u8; 64] = [0; 64]; // $ Alert[rust/hard-coded-cryptographic-value]
let key2 = Key::from(&array2); // $ Sink
_ = jar.private_mut(&key2);

let str3 = match(val) {
0 => "one",
1 => "two",
_ => "many"
}; // $ Alert[rust/hard-coded-cryptographic-value]
let key3 = Key::from(str3.as_bytes()); // $ Sink
_ = jar.signed_mut(&key3);

let array4: [u8; 3] = [
1,
2,
val as u8
]; // $ Alert[rust/hard-coded-cryptographic-value]
let key4 = Key::from(&array4); // $ Sink
_ = jar.signed_mut(&key4);
}

fn test_biscotti_crypto(array_var: &[u8]) {
Expand Down
Loading