Skip to content

Commit 03f962e

Browse files
authored
Merge pull request github#18226 from geoffw0/badcrypto
Rust: Weak encryption algorithm query.
2 parents a52a549 + 44a0ad2 commit 03f962e

File tree

20 files changed

+772
-34
lines changed

20 files changed

+772
-34
lines changed

config/identical-files.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,14 @@
234234
"CryptoAlgorithms Python/JS/Ruby": [
235235
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
236236
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
237-
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll"
237+
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll",
238+
"rust/ql/lib/codeql/rust/security/CryptoAlgorithms.qll"
238239
],
239240
"CryptoAlgorithmNames Python/JS/Ruby": [
240241
"javascript/ql/lib/semmle/javascript/security/internal/CryptoAlgorithmNames.qll",
241242
"python/ql/lib/semmle/python/concepts/internal/CryptoAlgorithmNames.qll",
242-
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll"
243+
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll",
244+
"rust/ql/lib/codeql/rust/security/internal/CryptoAlgorithmNames.qll"
243245
],
244246
"SensitiveDataHeuristics Python/JS": [
245247
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
@@ -254,7 +256,8 @@
254256
"Concepts Python/Ruby/JS": [
255257
"python/ql/lib/semmle/python/internal/ConceptsShared.qll",
256258
"ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll",
257-
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll"
259+
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll",
260+
"rust/ql/lib/codeql/rust/internal/ConceptsShared.qll"
258261
],
259262
"ApiGraphModels": [
260263
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",

javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Cryptography {
3030
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
3131

3232
/**
33-
* A data-flow node that is an application of a cryptographic algorithm. For example,
33+
* A data flow node that is an application of a cryptographic algorithm. For example,
3434
* encryption, decryption, signature-validation.
3535
*
3636
* Extend this class to refine existing API models. If you want to model new APIs,
@@ -40,7 +40,7 @@ module Cryptography {
4040
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
4141
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
4242

43-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
43+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
4444
DataFlow::Node getInitialization() { result = super.getInitialization() }
4545

4646
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
@@ -61,14 +61,14 @@ module Cryptography {
6161
/** Provides classes for modeling new applications of a cryptographic algorithms. */
6262
module CryptographicOperation {
6363
/**
64-
* A data-flow node that is an application of a cryptographic algorithm. For example,
64+
* A data flow node that is an application of a cryptographic algorithm. For example,
6565
* encryption, decryption, signature-validation.
6666
*
6767
* Extend this class to model new APIs. If you want to refine existing API models,
6868
* extend `CryptographicOperation` instead.
6969
*/
7070
abstract class Range extends DataFlow::Node {
71-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
71+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
7272
abstract DataFlow::Node getInitialization();
7373

7474
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
@@ -118,14 +118,14 @@ module Http {
118118
/** Provides classes for modeling HTTP clients. */
119119
module Client {
120120
/**
121-
* A data-flow node that makes an outgoing HTTP request.
121+
* A data flow node that makes an outgoing HTTP request.
122122
*
123123
* Extend this class to refine existing API models. If you want to model new APIs,
124124
* extend `Http::Client::Request::Range` instead.
125125
*/
126126
class Request extends DataFlow::Node instanceof Request::Range {
127127
/**
128-
* Gets a data-flow node that contributes to the URL of the request.
128+
* Gets a data flow node that contributes to the URL of the request.
129129
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
130130
*/
131131
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
@@ -150,14 +150,14 @@ module Http {
150150
/** Provides a class for modeling new HTTP requests. */
151151
module Request {
152152
/**
153-
* A data-flow node that makes an outgoing HTTP request.
153+
* A data flow node that makes an outgoing HTTP request.
154154
*
155155
* Extend this class to model new APIs. If you want to refine existing API models,
156156
* extend `Http::Client::Request` instead.
157157
*/
158158
abstract class Range extends DataFlow::Node {
159159
/**
160-
* Gets a data-flow node that contributes to the URL of the request.
160+
* Gets a data flow node that contributes to the URL of the request.
161161
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
162162
*/
163163
abstract DataFlow::Node getAUrlPart();

python/ql/lib/semmle/python/internal/ConceptsShared.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Cryptography {
3030
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
3131

3232
/**
33-
* A data-flow node that is an application of a cryptographic algorithm. For example,
33+
* A data flow node that is an application of a cryptographic algorithm. For example,
3434
* encryption, decryption, signature-validation.
3535
*
3636
* Extend this class to refine existing API models. If you want to model new APIs,
@@ -40,7 +40,7 @@ module Cryptography {
4040
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
4141
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
4242

43-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
43+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
4444
DataFlow::Node getInitialization() { result = super.getInitialization() }
4545

4646
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
@@ -61,14 +61,14 @@ module Cryptography {
6161
/** Provides classes for modeling new applications of a cryptographic algorithms. */
6262
module CryptographicOperation {
6363
/**
64-
* A data-flow node that is an application of a cryptographic algorithm. For example,
64+
* A data flow node that is an application of a cryptographic algorithm. For example,
6565
* encryption, decryption, signature-validation.
6666
*
6767
* Extend this class to model new APIs. If you want to refine existing API models,
6868
* extend `CryptographicOperation` instead.
6969
*/
7070
abstract class Range extends DataFlow::Node {
71-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
71+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
7272
abstract DataFlow::Node getInitialization();
7373

7474
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
@@ -118,14 +118,14 @@ module Http {
118118
/** Provides classes for modeling HTTP clients. */
119119
module Client {
120120
/**
121-
* A data-flow node that makes an outgoing HTTP request.
121+
* A data flow node that makes an outgoing HTTP request.
122122
*
123123
* Extend this class to refine existing API models. If you want to model new APIs,
124124
* extend `Http::Client::Request::Range` instead.
125125
*/
126126
class Request extends DataFlow::Node instanceof Request::Range {
127127
/**
128-
* Gets a data-flow node that contributes to the URL of the request.
128+
* Gets a data flow node that contributes to the URL of the request.
129129
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
130130
*/
131131
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
@@ -150,14 +150,14 @@ module Http {
150150
/** Provides a class for modeling new HTTP requests. */
151151
module Request {
152152
/**
153-
* A data-flow node that makes an outgoing HTTP request.
153+
* A data flow node that makes an outgoing HTTP request.
154154
*
155155
* Extend this class to model new APIs. If you want to refine existing API models,
156156
* extend `Http::Client::Request` instead.
157157
*/
158158
abstract class Range extends DataFlow::Node {
159159
/**
160-
* Gets a data-flow node that contributes to the URL of the request.
160+
* Gets a data flow node that contributes to the URL of the request.
161161
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
162162
*/
163163
abstract DataFlow::Node getAUrlPart();

ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Cryptography {
3030
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
3131

3232
/**
33-
* A data-flow node that is an application of a cryptographic algorithm. For example,
33+
* A data flow node that is an application of a cryptographic algorithm. For example,
3434
* encryption, decryption, signature-validation.
3535
*
3636
* Extend this class to refine existing API models. If you want to model new APIs,
@@ -40,7 +40,7 @@ module Cryptography {
4040
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
4141
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
4242

43-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
43+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
4444
DataFlow::Node getInitialization() { result = super.getInitialization() }
4545

4646
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
@@ -61,14 +61,14 @@ module Cryptography {
6161
/** Provides classes for modeling new applications of a cryptographic algorithms. */
6262
module CryptographicOperation {
6363
/**
64-
* A data-flow node that is an application of a cryptographic algorithm. For example,
64+
* A data flow node that is an application of a cryptographic algorithm. For example,
6565
* encryption, decryption, signature-validation.
6666
*
6767
* Extend this class to model new APIs. If you want to refine existing API models,
6868
* extend `CryptographicOperation` instead.
6969
*/
7070
abstract class Range extends DataFlow::Node {
71-
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
71+
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
7272
abstract DataFlow::Node getInitialization();
7373

7474
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
@@ -118,14 +118,14 @@ module Http {
118118
/** Provides classes for modeling HTTP clients. */
119119
module Client {
120120
/**
121-
* A data-flow node that makes an outgoing HTTP request.
121+
* A data flow node that makes an outgoing HTTP request.
122122
*
123123
* Extend this class to refine existing API models. If you want to model new APIs,
124124
* extend `Http::Client::Request::Range` instead.
125125
*/
126126
class Request extends DataFlow::Node instanceof Request::Range {
127127
/**
128-
* Gets a data-flow node that contributes to the URL of the request.
128+
* Gets a data flow node that contributes to the URL of the request.
129129
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
130130
*/
131131
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
@@ -150,14 +150,14 @@ module Http {
150150
/** Provides a class for modeling new HTTP requests. */
151151
module Request {
152152
/**
153-
* A data-flow node that makes an outgoing HTTP request.
153+
* A data flow node that makes an outgoing HTTP request.
154154
*
155155
* Extend this class to model new APIs. If you want to refine existing API models,
156156
* extend `Http::Client::Request` instead.
157157
*/
158158
abstract class Range extends DataFlow::Node {
159159
/**
160-
* Gets a data-flow node that contributes to the URL of the request.
160+
* Gets a data flow node that contributes to the URL of the request.
161161
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
162162
*/
163163
abstract DataFlow::Node getAUrlPart();

rust/ql/lib/codeql/rust/Concepts.qll

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ module RemoteSource {
105105
}
106106

107107
/**
108-
* A data-flow node that constructs a SQL statement (for later execution).
108+
* A data flow node that constructs a SQL statement (for later execution).
109109
*
110110
* Often, it is worthy of an alert if a SQL statement is constructed such that
111111
* executing it would be a security risk.
@@ -122,7 +122,7 @@ final class SqlConstruction = SqlConstruction::Range;
122122
*/
123123
module SqlConstruction {
124124
/**
125-
* A data-flow node that constructs a SQL statement.
125+
* A data flow node that constructs a SQL statement.
126126
*/
127127
abstract class Range extends DataFlow::Node {
128128
/**
@@ -133,7 +133,7 @@ module SqlConstruction {
133133
}
134134

135135
/**
136-
* A data-flow node that constructs and executes SQL statements.
136+
* A data flow node that constructs and executes SQL statements.
137137
*
138138
* If the context of interest is such that merely constructing a SQL statement
139139
* would be valuable to report, consider also using `SqlConstruction`.
@@ -148,7 +148,7 @@ final class SqlExecution = SqlExecution::Range;
148148
*/
149149
module SqlExecution {
150150
/**
151-
* A data-flow node that executes SQL statements.
151+
* A data flow node that executes SQL statements.
152152
*/
153153
abstract class Range extends DataFlow::Node {
154154
/**
@@ -159,7 +159,7 @@ module SqlExecution {
159159
}
160160

161161
/**
162-
* A data-flow node that performs SQL sanitization.
162+
* A data flow node that performs SQL sanitization.
163163
*/
164164
final class SqlSanitization = SqlSanitization::Range;
165165

@@ -168,7 +168,28 @@ final class SqlSanitization = SqlSanitization::Range;
168168
*/
169169
module SqlSanitization {
170170
/**
171-
* A data-flow node that performs SQL sanitization.
171+
* A data flow node that performs SQL sanitization.
172172
*/
173173
abstract class Range extends DataFlow::Node { }
174174
}
175+
176+
/**
177+
* Provides models for cryptographic things.
178+
*/
179+
module Cryptography {
180+
private import codeql.rust.internal.ConceptsShared::Cryptography as SC
181+
182+
final class CryptographicOperation = SC::CryptographicOperation;
183+
184+
class EncryptionAlgorithm = SC::EncryptionAlgorithm;
185+
186+
class HashingAlgorithm = SC::HashingAlgorithm;
187+
188+
class PasswordHashingAlgorithm = SC::PasswordHashingAlgorithm;
189+
190+
module CryptographicOperation = SC::CryptographicOperation;
191+
192+
class BlockMode = SC::BlockMode;
193+
194+
class CryptographicAlgorithm = SC::CryptographicAlgorithm;
195+
}

rust/ql/lib/codeql/rust/Frameworks.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
*/
44

55
private import codeql.rust.frameworks.Reqwest
6+
private import codeql.rust.frameworks.RustCrypto
67
private import codeql.rust.frameworks.stdlib.Env
78
private import codeql.rust.frameworks.Sqlx

rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ module Node {
330330
override ReturnKind getKind() { result = rk }
331331
}
332332

333-
/** A data-flow node that represents the output of a call. */
333+
/** A data flow node that represents the output of a call. */
334334
abstract class OutNode extends Node {
335335
/** Gets the underlying call for this node. */
336336
abstract DataFlowCall getCall(ReturnKind kind);
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Provides modeling for the `RustCrypto` family of crates (`cipher`, `digest` etc).
3+
*/
4+
5+
private import rust
6+
private import codeql.rust.Concepts
7+
private import codeql.rust.dataflow.DataFlow
8+
9+
bindingset[algorithmName]
10+
private string simplifyAlgorithmName(string algorithmName) {
11+
// the cipher library gives triple-DES names like "TdesEee2" and "TdesEde2"
12+
if algorithmName.matches("Tdes%") then result = "3des" else result = algorithmName
13+
}
14+
15+
/**
16+
* An operation that initializes a cipher through the `cipher::KeyInit` or
17+
* `cipher::KeyIvInit` trait, for example `Des::new` or `cbc::Encryptor<des::Des>::new`.
18+
*/
19+
class StreamCipherInit extends Cryptography::CryptographicOperation::Range {
20+
string algorithmName;
21+
22+
StreamCipherInit() {
23+
// a call to `cipher::KeyInit::new`, `cipher::KeyInit::new_from_slice`,
24+
// `cipher::KeyIvInit::new`, `cipher::KeyIvInit::new_from_slices` or `rc2::Rc2::new_with_eff_key_len`.
25+
exists(PathExpr p, string rawAlgorithmName |
26+
this.asExpr().getExpr().(CallExpr).getFunction() = p and
27+
p.getResolvedCrateOrigin().matches("%/RustCrypto%") and
28+
p.getPath().getPart().getNameRef().getText() =
29+
["new", "new_from_slice", "new_from_slices", "new_with_eff_key_len"] and
30+
(
31+
rawAlgorithmName = p.getPath().getQualifier().getPart().getNameRef().getText() or
32+
rawAlgorithmName =
33+
p.getPath()
34+
.getQualifier()
35+
.getPart()
36+
.getGenericArgList()
37+
.getGenericArg(0)
38+
.(TypeArg)
39+
.getTypeRepr()
40+
.(PathTypeRepr)
41+
.getPath()
42+
.getPart()
43+
.getNameRef()
44+
.getText()
45+
) and
46+
algorithmName = simplifyAlgorithmName(rawAlgorithmName)
47+
)
48+
}
49+
50+
override DataFlow::Node getInitialization() { result = this }
51+
52+
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(algorithmName) }
53+
54+
override DataFlow::Node getAnInput() { none() }
55+
56+
override Cryptography::BlockMode getBlockMode() { result = "" }
57+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* This file contains imports required for the Rust version of `ConceptsShared.qll`.
3+
* Since they are language-specific, they can't be placed directly in that file, as it is shared between languages.
4+
*/
5+
6+
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
7+
import codeql.rust.security.CryptoAlgorithms as CryptoAlgorithms

0 commit comments

Comments
 (0)