Skip to content

Commit 4215a89

Browse files
committed
Add cleartext storage database sinks
1 parent ac39aeb commit 4215a89

File tree

4 files changed

+532
-0
lines changed

4 files changed

+532
-0
lines changed

swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,61 @@ class RealmStore extends Stored instanceof DataFlow::PostUpdateNode {
5656
}
5757
}
5858

59+
/**
60+
* A `DataFlow::Node` that is an expression stored with the GRDB library.
61+
*/
62+
class GrdbStore extends Stored {
63+
GrdbStore() {
64+
exists(CallExpr call, MethodDecl method |
65+
call.getStaticTarget() = method and
66+
call.getArgumentWithLabel("arguments").getExpr() = this.asExpr()
67+
|
68+
method
69+
.hasQualifiedName("Database",
70+
["allStatements(sql:arguments:)", "execute(sql:arguments:)",])
71+
or
72+
method.hasQualifiedName("SQLRequest", "init(sql:arguments:adapter:cached:)")
73+
or
74+
method.hasQualifiedName("SQL", ["init(sql:arguments:)", "append(sql:arguments:)"])
75+
or
76+
method.hasQualifiedName("SQLStatementCursor", "init(database:sql:arguments:prepFlags:)")
77+
or
78+
method
79+
.hasQualifiedName("TableRecord",
80+
[
81+
"select(sql:arguments:)", "select(sql:arguments:as:)", "filter(sql:arguments:)",
82+
"order(sql:arguments:)"
83+
])
84+
or
85+
method
86+
.hasQualifiedName(["Row", "DatabaseValueConvertible", "FetchableRecord"],
87+
[
88+
"fetchCursor(_:sql:arguments:adapter:)", "fetchAll(_:sql:arguments:adapter:)",
89+
"fetchSet(_:sql:arguments:adapter:)", "fetchOne(_:sql:arguments:adapter:)"
90+
])
91+
or
92+
method
93+
.hasQualifiedName("FetchableRecord",
94+
[
95+
"fetchCursor(_:arguments:adapter:)", "fetchAll(_:arguments:adapter:)",
96+
"fetchSet(_:arguments:adapter:)", "fetchOne(_:arguments:adapter:)",
97+
])
98+
or
99+
method.hasQualifiedName("Statement", ["execute(arguments:)"])
100+
or
101+
method
102+
.hasQualifiedName("CommonTableExpression", "init(recursive:named:columns:sql:arguments:)")
103+
)
104+
or
105+
exists(CallExpr call, MethodDecl method |
106+
call.getStaticTarget() = method and
107+
call.getArgument(0).getExpr() = this.asExpr()
108+
|
109+
method.hasQualifiedName("Statement", "setArguments(_:)")
110+
)
111+
}
112+
}
113+
59114
/**
60115
* A taint configuration from sensitive information to expressions that are
61116
* transmitted over a network.
@@ -77,6 +132,14 @@ class CleartextStorageConfig extends TaintTracking::Configuration {
77132
node.asExpr() instanceof EncryptedExpr
78133
}
79134

135+
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
136+
// Needed until we have proper content flow through arrays
137+
exists(ArrayExpr arr |
138+
node1.asExpr() = arr.getAnElement() and
139+
node2.asExpr() = arr
140+
)
141+
}
142+
80143
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
81144
// flow out from fields of a `RealmSwiftObject` at the sink, for example in
82145
// `realmObj.data = sensitive`.

0 commit comments

Comments
 (0)