Skip to content

Commit 28998cc

Browse files
authored
Merge pull request github#12471 from geoffw0/dbsinks2
Swift: Better sinks for swift/cleartext-storage-database
2 parents 907053f + 170fde5 commit 28998cc

File tree

6 files changed

+275
-32
lines changed

6 files changed

+275
-32
lines changed

swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ private class CoreDataStore extends CleartextStorageDatabaseSink {
4848
// example in `coreDataObj.data = sensitive` the post-update node corresponding
4949
// with `coreDataObj.data` is a sink.
5050
// (ideally this would be only members with the `@NSManaged` attribute)
51-
exists(ClassOrStructDecl cd, Expr e |
52-
cd.getABaseTypeDecl*().getName() = "NSManagedObject" and
51+
exists(NominalType t, Expr e |
52+
t.getABaseType*().getName() = "NSManagedObject" and
5353
this.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = e and
54-
e.getFullyConverted().getType() = cd.getType() and
54+
e.getFullyConverted().getType() = t and
5555
not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl
5656
)
5757
}
@@ -66,10 +66,10 @@ private class RealmStore extends CleartextStorageDatabaseSink instanceof DataFlo
6666
// any write into a class derived from `RealmSwiftObject` is a sink. For
6767
// example in `realmObj.data = sensitive` the post-update node corresponding
6868
// with `realmObj.data` is a sink.
69-
exists(ClassOrStructDecl cd, Expr e |
70-
cd.getABaseTypeDecl*().getName() = "RealmSwiftObject" and
69+
exists(NominalType t, Expr e |
70+
t.getABaseType*().getName() = "RealmSwiftObject" and
7171
this.getPreUpdateNode().asExpr() = e and
72-
e.getFullyConverted().getType() = cd.getType() and
72+
e.getFullyConverted().getType() = t and
7373
not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl
7474
)
7575
}
@@ -122,15 +122,22 @@ private class CleartextStorageDatabaseEncryptionSanitizer extends CleartextStora
122122

123123
/**
124124
* An additional taint step for cleartext database storage vulnerabilities.
125-
* Needed until we have proper content flow through arrays.
126125
*/
127126
private class CleartextStorageDatabaseArrayAdditionalTaintStep extends CleartextStorageDatabaseAdditionalTaintStep
128127
{
129128
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
129+
// needed until we have proper content flow through arrays.
130130
exists(ArrayExpr arr |
131131
nodeFrom.asExpr() = arr.getAnElement() and
132132
nodeTo.asExpr() = arr
133133
)
134+
or
135+
// if an object is sensitive, its fields are always sensitive
136+
// (this is needed because the sensitive data sources are in a sense
137+
// approximate; for example we might identify `passwordBox` as a source,
138+
// whereas it is more accurate to say that `passwordBox.textField` is the
139+
// true source).
140+
nodeTo.asExpr().(MemberRefExpr).getBase() = nodeFrom.asExpr()
134141
}
135142
}
136143

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ DataFlow::Node cleanupNode(DataFlow::Node n) {
2626
result = n
2727
}
2828

29-
from CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
30-
where config.hasFlowPath(sourceNode, sinkNode)
31-
select cleanupNode(sinkNode.getNode()), sourceNode, sinkNode,
32-
"This operation stores '" + sinkNode.getNode().toString() +
29+
from
30+
CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode,
31+
DataFlow::Node cleanSink
32+
where
33+
config.hasFlowPath(sourceNode, sinkNode) and
34+
cleanSink = cleanupNode(sinkNode.getNode())
35+
select cleanSink, sourceNode, sinkNode,
36+
"This operation stores '" + cleanSink.toString() +
3337
"' in a database. It may contain unencrypted sensitive data from $@.", sourceNode,
3438
sourceNode.getNode().toString()

swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.ql

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ DataFlow::Node cleanupNode(DataFlow::Node n) {
2525
result = n
2626
}
2727

28-
from CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
29-
where config.hasFlowPath(sourceNode, sinkNode)
30-
select cleanupNode(sinkNode.getNode()), sourceNode, sinkNode,
31-
"This operation stores '" + sinkNode.getNode().toString() + "' in " +
28+
from
29+
CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode,
30+
DataFlow::Node cleanSink
31+
where
32+
config.hasFlowPath(sourceNode, sinkNode) and
33+
cleanSink = cleanupNode(sinkNode.getNode())
34+
select cleanSink, sourceNode, sinkNode,
35+
"This operation stores '" + cleanSink.toString() + "' in " +
3236
sinkNode.getNode().(CleartextStoragePreferencesSink).getStoreName() +
3337
". It may contain unencrypted sensitive data from $@.", sourceNode,
3438
sourceNode.getNode().toString()

0 commit comments

Comments
 (0)