Skip to content

Commit 077bcf6

Browse files
authored
Merge pull request #20740 from geoffw0/rustbarriers
Rust: Add numeric type barriers for three queries
2 parents d354b0c + c381153 commit 077bcf6

File tree

16 files changed

+232
-112
lines changed

16 files changed

+232
-112
lines changed

rust/ql/lib/codeql/rust/frameworks/stdlib/Builtins.qll

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ class BuiltinType extends Struct {
3131
string getName() { result = super.getName().getText() }
3232
}
3333

34+
/**
35+
* A numerical type, such as `i64`, `usize`, `f32` or `f64`.
36+
*/
37+
abstract private class NumericTypeImpl extends BuiltinType { }
38+
39+
final class NumericType = NumericTypeImpl;
40+
41+
/**
42+
* An integral numerical type, such as `i64` or `usize`.
43+
*/
44+
abstract private class IntegralTypeImpl extends NumericTypeImpl { }
45+
46+
final class IntegralType = IntegralTypeImpl;
47+
48+
/**
49+
* A floating-point numerical type, such as `f32` or `f64`.
50+
*/
51+
abstract private class FloatingPointTypeImpl extends NumericTypeImpl { }
52+
53+
final class FloatingPointType = FloatingPointTypeImpl;
54+
3455
/** The builtin `bool` type. */
3556
class Bool extends BuiltinType {
3657
Bool() { this.getName() = "bool" }
@@ -47,71 +68,71 @@ class Str extends BuiltinType {
4768
}
4869

4970
/** The builtin `i8` type. */
50-
class I8 extends BuiltinType {
71+
class I8 extends IntegralTypeImpl {
5172
I8() { this.getName() = "i8" }
5273
}
5374

5475
/** The builtin `i16` type. */
55-
class I16 extends BuiltinType {
76+
class I16 extends IntegralTypeImpl {
5677
I16() { this.getName() = "i16" }
5778
}
5879

5980
/** The builtin `i32` type. */
60-
class I32 extends BuiltinType {
81+
class I32 extends IntegralTypeImpl {
6182
I32() { this.getName() = "i32" }
6283
}
6384

6485
/** The builtin `i64` type. */
65-
class I64 extends BuiltinType {
86+
class I64 extends IntegralTypeImpl {
6687
I64() { this.getName() = "i64" }
6788
}
6889

6990
/** The builtin `i128` type. */
70-
class I128 extends BuiltinType {
91+
class I128 extends IntegralTypeImpl {
7192
I128() { this.getName() = "i128" }
7293
}
7394

7495
/** The builtin `u8` type. */
75-
class U8 extends BuiltinType {
96+
class U8 extends IntegralTypeImpl {
7697
U8() { this.getName() = "u8" }
7798
}
7899

79100
/** The builtin `u16` type. */
80-
class U16 extends BuiltinType {
101+
class U16 extends IntegralTypeImpl {
81102
U16() { this.getName() = "u16" }
82103
}
83104

84105
/** The builtin `u32` type. */
85-
class U32 extends BuiltinType {
106+
class U32 extends IntegralTypeImpl {
86107
U32() { this.getName() = "u32" }
87108
}
88109

89110
/** The builtin `u64` type. */
90-
class U64 extends BuiltinType {
111+
class U64 extends IntegralTypeImpl {
91112
U64() { this.getName() = "u64" }
92113
}
93114

94115
/** The builtin `u128` type. */
95-
class U128 extends BuiltinType {
116+
class U128 extends IntegralTypeImpl {
96117
U128() { this.getName() = "u128" }
97118
}
98119

99120
/** The builtin `usize` type. */
100-
class Usize extends BuiltinType {
121+
class Usize extends IntegralTypeImpl {
101122
Usize() { this.getName() = "usize" }
102123
}
103124

104125
/** The builtin `isize` type. */
105-
class Isize extends BuiltinType {
126+
class Isize extends IntegralTypeImpl {
106127
Isize() { this.getName() = "isize" }
107128
}
108129

109130
/** The builtin `f32` type. */
110-
class F32 extends BuiltinType {
131+
class F32 extends FloatingPointTypeImpl {
111132
F32() { this.getName() = "f32" }
112133
}
113134

114135
/** The builtin `f64` type. */
115-
class F64 extends BuiltinType {
136+
class F64 extends FloatingPointTypeImpl {
116137
F64() { this.getName() = "f64" }
117138
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Classes to represent barriers commonly used in dataflow and taint tracking
3+
* configurations.
4+
*/
5+
6+
import rust
7+
private import codeql.rust.dataflow.DataFlow
8+
private import codeql.rust.internal.TypeInference as TypeInference
9+
private import codeql.rust.internal.Type
10+
private import codeql.rust.frameworks.stdlib.Builtins
11+
12+
/**
13+
* A node whose type is a numeric or boolean type, which may be an appropriate
14+
* taint flow barrier for some queries.
15+
*/
16+
class NumericTypeBarrier extends DataFlow::Node {
17+
NumericTypeBarrier() {
18+
exists(StructType t, Struct s |
19+
t = TypeInference::inferType(this.asExpr().getExpr()) and
20+
s = t.getStruct()
21+
|
22+
s instanceof NumericType or
23+
s instanceof Bool
24+
)
25+
}
26+
}
27+
28+
/**
29+
* A node whose type is an integral (integer) or boolean type, which may be an
30+
* appropriate taint flow barrier for some queries.
31+
*/
32+
class IntegralOrBooleanTypeBarrier extends DataFlow::Node {
33+
IntegralOrBooleanTypeBarrier() {
34+
exists(StructType t, Struct s |
35+
t = TypeInference::inferType(this.asExpr().getExpr()) and
36+
s = t.getStruct()
37+
|
38+
s instanceof IntegralType or
39+
s instanceof Bool
40+
)
41+
}
42+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import codeql.rust.dataflow.DataFlow
88
private import codeql.rust.dataflow.FlowSink
99
private import codeql.rust.Concepts
1010
private import codeql.util.Unit
11+
private import codeql.rust.security.Barriers as Barriers
1112

1213
/**
1314
* Provides default sources, sinks and barriers for detecting log injection
@@ -42,4 +43,10 @@ module LogInjection {
4243
private class ModelsAsDataSink extends Sink {
4344
ModelsAsDataSink() { sinkNode(this, "log-injection") }
4445
}
46+
47+
/**
48+
* A barrier for log injection vulnerabilities for nodes whose type is a
49+
* numeric or boolean type, which is unlikely to expose any vulnerability.
50+
*/
51+
private class NumericTypeBarrier extends Barrier instanceof Barriers::NumericTypeBarrier { }
4552
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import codeql.rust.dataflow.DataFlow
99
private import codeql.rust.dataflow.FlowSink
1010
private import codeql.rust.Concepts
1111
private import codeql.util.Unit
12+
private import codeql.rust.security.Barriers as Barriers
1213

1314
/**
1415
* Provides default sources, sinks and barriers for detecting SQL injection
@@ -57,4 +58,10 @@ module SqlInjection {
5758
private class ModelsAsDataSink extends Sink {
5859
ModelsAsDataSink() { sinkNode(this, "sql-injection") }
5960
}
61+
62+
/**
63+
* A barrier for SQL injection vulnerabilities for nodes whose type is a numeric or
64+
* boolean type, which is unlikely to expose any vulnerability.
65+
*/
66+
private class NumericTypeBarrier extends Barrier instanceof Barriers::NumericTypeBarrier { }
6067
}

rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import codeql.rust.dataflow.DataFlow
99
private import codeql.rust.controlflow.CfgNodes
1010
private import codeql.rust.dataflow.FlowSink
1111
private import codeql.rust.Concepts
12+
private import codeql.rust.security.Barriers as Barriers
1213

1314
/**
1415
* Provides default sources, sinks and barriers for detecting regular expression
@@ -87,4 +88,14 @@ module RegexInjection {
8788
.getText() = "escape"
8889
}
8990
}
91+
92+
/**
93+
* A barrier for regular expression injection vulnerabilities for nodes whose
94+
* type is an integral or boolean type, which is unlikely to expose any vulnerability.
95+
*
96+
* We don't include floating point types in this barrier, as `.` is a special character
97+
* in regular expressions.
98+
*/
99+
private class IntegralOrBooleanTypeBarrier extends Barrier instanceof Barriers::IntegralOrBooleanTypeBarrier
100+
{ }
90101
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Taint flow barriers have been added to the `rust/regex-injection`, `rust/sql-injection` and `rust/log-injection`, reducing the frequency of false positive results for these queries.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
| struct bool | |
2+
| struct char | |
3+
| struct f32 | FloatingPointType, NumericType |
4+
| struct f64 | FloatingPointType, NumericType |
5+
| struct i8 | IntegralType, NumericType |
6+
| struct i16 | IntegralType, NumericType |
7+
| struct i32 | IntegralType, NumericType |
8+
| struct i64 | IntegralType, NumericType |
9+
| struct i128 | IntegralType, NumericType |
10+
| struct isize | IntegralType, NumericType |
11+
| struct str | |
12+
| struct u8 | IntegralType, NumericType |
13+
| struct u16 | IntegralType, NumericType |
14+
| struct u32 | IntegralType, NumericType |
15+
| struct u64 | IntegralType, NumericType |
16+
| struct u128 | IntegralType, NumericType |
17+
| struct usize | IntegralType, NumericType |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import rust
2+
import codeql.rust.frameworks.stdlib.Builtins
3+
import codeql.rust.internal.Type
4+
5+
string describe(BuiltinType t) {
6+
t instanceof NumericType and result = "NumericType"
7+
or
8+
t instanceof IntegralType and result = "IntegralType"
9+
or
10+
t instanceof FloatingPointType and result = "FloatingPointType"
11+
}
12+
13+
from BuiltinType t
14+
select t.toString(), concat(describe(t), ", ")

rust/ql/test/library-tests/elements/builtintypes/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
// --- tests ---
3+
4+
fn test_types() {
5+
}

0 commit comments

Comments
 (0)