Skip to content

Commit 6efc19d

Browse files
authored
Merge pull request #18943 from geoffw0/constcrypto
Rust: new query rust/hardcoded-crytographic-value
2 parents 96a32c0 + f7d822b commit 6efc19d

20 files changed

+574
-2
lines changed

rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
1515
ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
1616
ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql
1717
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
18+
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
1819
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
1920
ql/rust/ql/src/queries/summary/LinesOfCode.ql
2021
ql/rust/ql/src/queries/summary/LinesOfUserCode.ql

rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
1616
ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql
1717
ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql
1818
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
19+
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
1920
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
2021
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
2122
ql/rust/ql/src/queries/summary/LinesOfCode.ql

rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
1515
ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
1616
ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql
1717
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
18+
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
1819
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
1920
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
2021
ql/rust/ql/src/queries/summary/LinesOfCode.ql
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/rust-all
4+
extensible: summaryModel
5+
data:
6+
- ["<generic_array::GenericArray>::from_slice", "Argument[0].Reference", "ReturnValue.Reference", "value", "manual"]
7+
- ["<generic_array::GenericArray>::from_mut_slice", "Argument[0].Reference", "ReturnValue.Reference", "value", "manual"]
8+
- ["<generic_array::GenericArray>::try_from_slice", "Argument[0].Reference", "ReturnValue.Field[crate::result::Result::Ok(0)].Reference", "value", "manual"]
9+
- ["<generic_array::GenericArray>::try_from_mut_slice", "Argument[0].Reference", "ReturnValue.Field[crate::result::Result::Ok(0)].Reference", "value", "manual"]

rust/ql/lib/codeql/rust/frameworks/rustcrypto/rustcrypto.model.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,28 @@ extensions:
88
- ["<_ as digest::digest::Digest>::chain_update", "Argument[0]", "hasher-input", "manual"]
99
- ["<_ as digest::digest::Digest>::digest", "Argument[0]", "hasher-input", "manual"]
1010
- ["md5::compute", "Argument[0]", "hasher-input", "manual"]
11+
- ["<_ as crypto_common::KeyInit>::new", "Argument[0]", "credentials-key", "manual"]
12+
- ["<_ as crypto_common::KeyInit>::new", "Argument[1]", "credentials-iv", "manual"]
13+
- ["<_ as crypto_common::KeyInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
14+
- ["<_ as crypto_common::KeyInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
15+
- ["<_ as crypto_common::KeyIvInit>::new", "Argument[0]", "credentials-key", "manual"]
16+
- ["<_ as crypto_common::KeyIvInit>::new", "Argument[1]", "credentials-iv", "manual"]
17+
- ["<_ as crypto_common::KeyIvInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
18+
- ["<_ as crypto_common::KeyIvInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
19+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyInit>::new", "Argument[0]", "credentials-key", "manual"]
20+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyInit>::new", "Argument[1]", "credentials-iv", "manual"]
21+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
22+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
23+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyIvInit>::new", "Argument[0]", "credentials-key", "manual"]
24+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyIvInit>::new", "Argument[1]", "credentials-iv", "manual"]
25+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyIvInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
26+
- ["<cipher::stream_wrapper::StreamCipherCoreWrapper as crypto_common::KeyIvInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
27+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyInit>::new", "Argument[0]", "credentials-key", "manual"]
28+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyInit>::new", "Argument[1]", "credentials-iv", "manual"]
29+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
30+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
31+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyIvInit>::new", "Argument[0]", "credentials-key", "manual"]
32+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyIvInit>::new", "Argument[1]", "credentials-iv", "manual"]
33+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyIvInit>::new_from_slice", "Argument[0]", "credentials-key", "manual"]
34+
- ["<digest::core_api::wrapper::CoreWrapper as crypto_common::KeyIvInit>::new_from_slice", "Argument[1]", "credentials-iv", "manual"]
35+
- ["<_ as aead::Aead>::encrypt", "Argument[0]", "credentials-nonce", "manual"]

rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ extensions:
33
pack: codeql/rust-all
44
extensible: summaryModel
55
data:
6+
# Conversions
7+
- ["<core::alloc::layout::Layout>::align_to", "Argument[self].Element", "ReturnValue.Field[0,1,2].Reference.Element", "taint", "manual"]
8+
- ["<_ as core::convert::Into>::into", "Argument[self].Element", "ReturnValue.Element", "taint", "manual"]
9+
- ["<_ as core::convert::Into>::into", "Argument[self].Reference.Element", "ReturnValue.Element", "taint", "manual"]
10+
- ["<alloc::string::String as core::convert::Into>::into", "Argument[self].Element", "ReturnValue.Element", "taint", "manual"]
11+
- ["<alloc::string::String as core::convert::Into>::into", "Argument[self].Reference.Element", "ReturnValue.Element", "taint", "manual"]
612
# Iterator
713
- ["<core::result::Result>::iter", "Argument[self].Element", "ReturnValue.Element", "value", "manual"]
814
- ["<alloc::vec::Vec as value_trait::array::Array>::iter", "Argument[self].Element", "ReturnValue.Element", "value", "manual"]
@@ -59,6 +65,8 @@ extensions:
5965
pack: codeql/rust-all
6066
extensible: sourceModel
6167
data:
68+
# Mem
69+
- ["core::mem::zeroed", "ReturnValue.Element", "constant-source", "manual"]
6270
# Ptr
6371
- ["core::ptr::drop_in_place", "Argument[0]", "pointer-invalidate", "manual"]
6472
- ["core::ptr::dangling", "ReturnValue", "pointer-invalidate", "manual"]

rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import rust
77
private import codeql.rust.dataflow.DataFlow
8-
private import codeql.rust.dataflow.internal.DataFlowImpl
8+
private import codeql.rust.dataflow.FlowSink
99
private import codeql.rust.security.SensitiveData
1010
private import codeql.rust.Concepts
1111

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Provides classes and predicates for reasoning about hard-coded cryptographic value
3+
* vulnerabilities.
4+
*/
5+
6+
import rust
7+
private import codeql.rust.dataflow.DataFlow
8+
private import codeql.rust.dataflow.FlowSource
9+
private import codeql.rust.dataflow.FlowSink
10+
private import codeql.rust.Concepts
11+
private import codeql.rust.security.SensitiveData
12+
13+
/**
14+
* A kind of cryptographic value.
15+
*/
16+
class CryptographicValueKind extends string {
17+
CryptographicValueKind() { this = ["password", "key", "iv", "nonce", "salt"] }
18+
19+
/**
20+
* Gets a description of this value kind for user-facing messages.
21+
*/
22+
string getDescription() {
23+
this = "password" and result = "a password"
24+
or
25+
this = "key" and result = "a key"
26+
or
27+
this = "iv" and result = "an initialization vector"
28+
or
29+
this = "nonce" and result = "a nonce"
30+
or
31+
this = "salt" and result = "a salt"
32+
}
33+
}
34+
35+
/**
36+
* Provides default sources, sinks and barriers for detecting hard-coded cryptographic
37+
* value vulnerabilities, as well as extension points for adding your own.
38+
*/
39+
module HardcodedCryptographicValue {
40+
/**
41+
* A data flow source for hard-coded cryptographic value vulnerabilities.
42+
*/
43+
abstract class Source extends DataFlow::Node { }
44+
45+
/**
46+
* A data flow sink for hard-coded cryptographic value vulnerabilities.
47+
*/
48+
abstract class Sink extends QuerySink::Range {
49+
override string getSinkType() { result = "HardcodedCryptographicValue" }
50+
51+
/**
52+
* Gets the kind of credential this sink is interpreted as.
53+
*/
54+
abstract CryptographicValueKind getKind();
55+
}
56+
57+
/**
58+
* A barrier for hard-coded cryptographic value vulnerabilities.
59+
*/
60+
abstract class Barrier extends DataFlow::Node { }
61+
62+
/**
63+
* A literal, considered as a flow source.
64+
*/
65+
private class LiteralSource extends Source {
66+
LiteralSource() { this.asExpr().getExpr() instanceof LiteralExpr }
67+
}
68+
69+
/**
70+
* An array initialized from a list of literals, considered as a single flow source. For example:
71+
* ```
72+
* `[0, 0, 0, 0]`
73+
* ```
74+
*/
75+
private class ArrayListSource extends Source {
76+
ArrayListSource() { this.asExpr().getExpr().(ArrayListExpr).getExpr(_) instanceof LiteralExpr }
77+
}
78+
79+
/**
80+
* An externally modeled source for constant values.
81+
*/
82+
private class ModeledSource extends Source {
83+
ModeledSource() { sourceNode(this, "constant-source") }
84+
}
85+
86+
/**
87+
* An externally modeled sink for hard-coded cryptographic value vulnerabilities.
88+
*/
89+
private class ModelsAsDataSinks extends Sink {
90+
CryptographicValueKind kind;
91+
92+
ModelsAsDataSinks() { sinkNode(this, "credentials-" + kind) }
93+
94+
override CryptographicValueKind getKind() { result = kind }
95+
}
96+
97+
/**
98+
* A call to `getrandom` that is a barrier.
99+
*/
100+
private class GetRandomBarrier extends Barrier {
101+
GetRandomBarrier() {
102+
exists(CallExprBase ce |
103+
ce.getStaticTarget().(Addressable).getCanonicalPath() =
104+
["getrandom::fill", "getrandom::getrandom"] and
105+
this.asExpr().getExpr().getParentNode*() = ce.getArgList().getArg(0)
106+
)
107+
}
108+
}
109+
}

rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import rust
88
private import codeql.rust.dataflow.DataFlow
9-
private import codeql.rust.dataflow.internal.DataFlowImpl
9+
private import codeql.rust.dataflow.FlowSink
1010
private import codeql.rust.Concepts
1111
private import codeql.util.Unit
1212

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: newQuery
3+
---
4+
* Added a new query, `rust/hardcoded-crytographic-value`, for detecting use of hardcoded keys, passwords, salts and initialization vectors.

0 commit comments

Comments
 (0)