Skip to content

Commit 3126fb9

Browse files
committed
Swift: Core Data support.
1 parent 456ab98 commit 3126fb9

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

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

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,51 @@
1111
*/
1212

1313
import swift
14+
import codeql.swift.security.SensitiveExprs
1415
import codeql.swift.dataflow.DataFlow
16+
import codeql.swift.dataflow.TaintTracking
1517
import DataFlow::PathGraph
1618

17-
select "TODO"
19+
abstract class Stored extends Expr { }
20+
21+
class CoreDataStore extends Stored {
22+
CoreDataStore() {
23+
// `content` arg to `NWConnection.send` is a sink
24+
exists(ClassDecl c, AbstractFunctionDecl f, CallExpr call |
25+
c.getName() = "NSManagedObject" and
26+
c.getAMember() = f and
27+
f.getName() = ["setValue(_:forKey:)", "setPrimitiveValue(_:forKey:)"] and
28+
call.getFunction().(ApplyExpr).getStaticTarget() = f and
29+
call.getArgument(0).getExpr() = this
30+
)
31+
}
32+
}
33+
34+
/**
35+
* A taint configuration from sensitive information to expressions that are
36+
* transmitted over a network.
37+
*/
38+
class CleartextStorageConfig extends TaintTracking::Configuration {
39+
CleartextStorageConfig() { this = "CleartextStorageConfig" }
40+
41+
override predicate isSource(DataFlow::Node node) {
42+
exists(SensitiveExpr e |
43+
node.asExpr() = e and
44+
not e.isProbablySafe()
45+
)
46+
}
47+
48+
override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof Stored }
49+
50+
override predicate isSanitizerIn(DataFlow::Node node) {
51+
// make sources barriers so that we only report the closest instance
52+
isSource(node)
53+
}
54+
}
55+
56+
from CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
57+
where config.hasFlowPath(sourceNode, sinkNode)
58+
select sinkNode.getNode(), sourceNode, sinkNode,
59+
"This operation stores '" + sinkNode.getNode().toString() +
60+
"' in a database. It may contain unencrypted sensitive data from $@", sourceNode,
61+
sourceNode.getNode().toString()
Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,68 @@
11
edges
2+
| testCoreData.swift:37:14:37:22 | WriteDef : | testCoreData.swift:37:49:37:49 | data : |
3+
| testCoreData.swift:37:14:37:22 | data : | testCoreData.swift:37:49:37:49 | data : |
4+
| testCoreData.swift:38:11:38:23 | WriteDef : | testCoreData.swift:38:1:38:33 | data[return] : |
5+
| testCoreData.swift:38:11:38:23 | data : | testCoreData.swift:38:1:38:33 | data[return] : |
6+
| testCoreData.swift:77:24:77:24 | x : | testCoreData.swift:78:15:78:15 | x |
7+
| testCoreData.swift:80:10:80:22 | call to getPassword() : | testCoreData.swift:81:15:81:15 | y |
8+
| testCoreData.swift:91:10:91:10 | passwd : | testCoreData.swift:95:15:95:15 | x |
9+
| testCoreData.swift:91:10:91:10 | passwd : | testCoreData.swift:99:14:99:14 | x : |
10+
| testCoreData.swift:92:10:92:10 | passwd : | testCoreData.swift:96:15:96:15 | y |
11+
| testCoreData.swift:92:10:92:10 | passwd : | testCoreData.swift:100:13:100:14 | &... : |
12+
| testCoreData.swift:93:10:93:10 | passwd : | testCoreData.swift:97:15:97:15 | z |
13+
| testCoreData.swift:99:6:99:15 | call to encrypt(_:) : | testCoreData.swift:103:15:103:15 | x |
14+
| testCoreData.swift:99:14:99:14 | x : | testCoreData.swift:37:14:37:22 | WriteDef : |
15+
| testCoreData.swift:99:14:99:14 | x : | testCoreData.swift:37:14:37:22 | data : |
16+
| testCoreData.swift:99:14:99:14 | x : | testCoreData.swift:99:6:99:15 | call to encrypt(_:) : |
17+
| testCoreData.swift:100:7:100:14 | data: &... : | testCoreData.swift:104:15:104:15 | y |
18+
| testCoreData.swift:100:13:100:14 | &... : | testCoreData.swift:38:11:38:23 | WriteDef : |
19+
| testCoreData.swift:100:13:100:14 | &... : | testCoreData.swift:38:11:38:23 | data : |
20+
| testCoreData.swift:100:13:100:14 | &... : | testCoreData.swift:100:7:100:14 | data: &... : |
221
nodes
22+
| testCoreData.swift:37:14:37:22 | WriteDef : | semmle.label | WriteDef : |
23+
| testCoreData.swift:37:14:37:22 | WriteDef : | semmle.label | data : |
24+
| testCoreData.swift:37:14:37:22 | data : | semmle.label | WriteDef : |
25+
| testCoreData.swift:37:14:37:22 | data : | semmle.label | data : |
26+
| testCoreData.swift:37:49:37:49 | data : | semmle.label | data : |
27+
| testCoreData.swift:38:1:38:33 | data[return] : | semmle.label | data[return] : |
28+
| testCoreData.swift:38:11:38:23 | WriteDef : | semmle.label | WriteDef : |
29+
| testCoreData.swift:38:11:38:23 | WriteDef : | semmle.label | data : |
30+
| testCoreData.swift:38:11:38:23 | data : | semmle.label | WriteDef : |
31+
| testCoreData.swift:38:11:38:23 | data : | semmle.label | data : |
32+
| testCoreData.swift:48:15:48:15 | password | semmle.label | password |
33+
| testCoreData.swift:51:24:51:24 | password | semmle.label | password |
34+
| testCoreData.swift:58:15:58:15 | password | semmle.label | password |
35+
| testCoreData.swift:77:24:77:24 | x : | semmle.label | x : |
36+
| testCoreData.swift:78:15:78:15 | x | semmle.label | x |
37+
| testCoreData.swift:80:10:80:22 | call to getPassword() : | semmle.label | call to getPassword() : |
38+
| testCoreData.swift:81:15:81:15 | y | semmle.label | y |
39+
| testCoreData.swift:85:15:85:17 | .password | semmle.label | .password |
40+
| testCoreData.swift:91:10:91:10 | passwd : | semmle.label | passwd : |
41+
| testCoreData.swift:92:10:92:10 | passwd : | semmle.label | passwd : |
42+
| testCoreData.swift:93:10:93:10 | passwd : | semmle.label | passwd : |
43+
| testCoreData.swift:95:15:95:15 | x | semmle.label | x |
44+
| testCoreData.swift:96:15:96:15 | y | semmle.label | y |
45+
| testCoreData.swift:97:15:97:15 | z | semmle.label | z |
46+
| testCoreData.swift:99:6:99:15 | call to encrypt(_:) : | semmle.label | call to encrypt(_:) : |
47+
| testCoreData.swift:99:14:99:14 | x : | semmle.label | x : |
48+
| testCoreData.swift:100:7:100:14 | data: &... : | semmle.label | data: &... : |
49+
| testCoreData.swift:100:13:100:14 | &... : | semmle.label | &... : |
50+
| testCoreData.swift:103:15:103:15 | x | semmle.label | x |
51+
| testCoreData.swift:104:15:104:15 | y | semmle.label | y |
352
subpaths
53+
| testCoreData.swift:99:14:99:14 | x : | testCoreData.swift:37:14:37:22 | WriteDef : | testCoreData.swift:37:49:37:49 | data : | testCoreData.swift:99:6:99:15 | call to encrypt(_:) : |
54+
| testCoreData.swift:99:14:99:14 | x : | testCoreData.swift:37:14:37:22 | data : | testCoreData.swift:37:49:37:49 | data : | testCoreData.swift:99:6:99:15 | call to encrypt(_:) : |
55+
| testCoreData.swift:100:13:100:14 | &... : | testCoreData.swift:38:11:38:23 | WriteDef : | testCoreData.swift:38:1:38:33 | data[return] : | testCoreData.swift:100:7:100:14 | data: &... : |
56+
| testCoreData.swift:100:13:100:14 | &... : | testCoreData.swift:38:11:38:23 | data : | testCoreData.swift:38:1:38:33 | data[return] : | testCoreData.swift:100:7:100:14 | data: &... : |
457
#select
5-
| TODO |
58+
| testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:48:15:48:15 | password | password |
59+
| testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:51:24:51:24 | password | password |
60+
| testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:58:15:58:15 | password | password |
61+
| testCoreData.swift:78:15:78:15 | x | testCoreData.swift:77:24:77:24 | x : | testCoreData.swift:78:15:78:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:77:24:77:24 | x : | x |
62+
| testCoreData.swift:81:15:81:15 | y | testCoreData.swift:80:10:80:22 | call to getPassword() : | testCoreData.swift:81:15:81:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:80:10:80:22 | call to getPassword() : | call to getPassword() |
63+
| testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | This operation stores '.password' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:85:15:85:17 | .password | .password |
64+
| testCoreData.swift:95:15:95:15 | x | testCoreData.swift:91:10:91:10 | passwd : | testCoreData.swift:95:15:95:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:91:10:91:10 | passwd : | passwd |
65+
| testCoreData.swift:96:15:96:15 | y | testCoreData.swift:92:10:92:10 | passwd : | testCoreData.swift:96:15:96:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:92:10:92:10 | passwd : | passwd |
66+
| testCoreData.swift:97:15:97:15 | z | testCoreData.swift:93:10:93:10 | passwd : | testCoreData.swift:97:15:97:15 | z | This operation stores 'z' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:93:10:93:10 | passwd : | passwd |
67+
| testCoreData.swift:103:15:103:15 | x | testCoreData.swift:91:10:91:10 | passwd : | testCoreData.swift:103:15:103:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:91:10:91:10 | passwd : | passwd |
68+
| testCoreData.swift:104:15:104:15 | y | testCoreData.swift:92:10:92:10 | passwd : | testCoreData.swift:104:15:104:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@ | testCoreData.swift:92:10:92:10 | passwd : | passwd |

0 commit comments

Comments
 (0)