mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Swift: Detect Realm sinks more reliably.
This commit is contained in:
@@ -57,6 +57,26 @@ private class CoreDataStore extends CleartextStorageDatabaseSink {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Realm database `RealmSwiftObject` type. Also matches the Realm `Object`
|
||||
* type, which may or may not be a type alias for `RealmSwiftObject`.
|
||||
*/
|
||||
class RealmSwiftObject extends Type {
|
||||
RealmSwiftObject() {
|
||||
this.getName() = "RealmSwiftObject"
|
||||
or
|
||||
this.getName() = "Object" and
|
||||
this.(NominalType).getDeclaration().getModule().getName() = "RealmSwift"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that inherits from `RealmSwiftObject`.
|
||||
*/
|
||||
class RealmSwiftObjectType extends Type {
|
||||
RealmSwiftObjectType() { this.getUnderlyingType().getABaseType*() instanceof RealmSwiftObject }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `DataFlow::Node` that is an expression stored with the Realm database
|
||||
* library.
|
||||
@@ -66,10 +86,9 @@ private class RealmStore extends CleartextStorageDatabaseSink instanceof DataFlo
|
||||
// any write into a class derived from `RealmSwiftObject` is a sink. For
|
||||
// example in `realmObj.data = sensitive` the post-update node corresponding
|
||||
// with `realmObj.data` is a sink.
|
||||
exists(NominalType t, Type base, Expr e |
|
||||
base.getName() = "RealmSwiftObject" and
|
||||
exists(Expr e |
|
||||
this.getPreUpdateNode().asExpr() = e and
|
||||
e.getFullyConverted().getType().getUnderlyingType().getABaseType*() = base and
|
||||
e.getFullyConverted().getType() instanceof RealmSwiftObjectType and
|
||||
not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,8 +34,10 @@ module CleartextStorageDatabaseConfig implements DataFlow::ConfigSig {
|
||||
// for example in `realmObj.data = sensitive`.
|
||||
isSink(node) and
|
||||
exists(NominalTypeDecl d, Decl cx |
|
||||
d.getType().getUnderlyingType().getABaseType*().getName() =
|
||||
["NSManagedObject", "RealmSwiftObject"] and
|
||||
(
|
||||
d.getType().getUnderlyingType().getABaseType*().getName() = "NSManagedObject" or
|
||||
d.getType() instanceof RealmSwiftObjectType
|
||||
) and
|
||||
cx.asNominalTypeDecl() = d and
|
||||
c.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember()
|
||||
)
|
||||
|
||||
@@ -73,6 +73,7 @@ edges
|
||||
| file://:0:0:0:0 | self | file://:0:0:0:0 | .value2 |
|
||||
| file://:0:0:0:0 | self [value] | file://:0:0:0:0 | .value |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [data] |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [data] |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [password] |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [value] |
|
||||
@@ -288,6 +289,10 @@ edges
|
||||
| testGRDB.swift:210:85:210:85 | password | testGRDB.swift:210:84:210:93 | [...] [Collection element] |
|
||||
| testGRDB.swift:212:98:212:107 | [...] [Collection element] | testGRDB.swift:212:98:212:107 | [...] |
|
||||
| testGRDB.swift:212:99:212:99 | password | testGRDB.swift:212:98:212:107 | [...] [Collection element] |
|
||||
| testRealm2.swift:13:6:13:6 | value | file://:0:0:0:0 | value |
|
||||
| testRealm2.swift:18:2:18:2 | [post] o [data] | testRealm2.swift:18:2:18:2 | [post] o |
|
||||
| testRealm2.swift:18:11:18:11 | myPassword | testRealm2.swift:13:6:13:6 | value |
|
||||
| testRealm2.swift:18:11:18:11 | myPassword | testRealm2.swift:18:2:18:2 | [post] o [data] |
|
||||
| testRealm.swift:27:6:27:6 | value | file://:0:0:0:0 | value |
|
||||
| testRealm.swift:34:6:34:6 | value | file://:0:0:0:0 | value |
|
||||
| testRealm.swift:41:2:41:2 | [post] a [data] | testRealm.swift:41:2:41:2 | [post] a |
|
||||
@@ -405,6 +410,7 @@ nodes
|
||||
| file://:0:0:0:0 | .value | semmle.label | .value |
|
||||
| file://:0:0:0:0 | .value2 | semmle.label | .value2 |
|
||||
| file://:0:0:0:0 | [post] self [data] | semmle.label | [post] self [data] |
|
||||
| file://:0:0:0:0 | [post] self [data] | semmle.label | [post] self [data] |
|
||||
| file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] | semmle.label | [post] self [notStoredBankAccountNumber] |
|
||||
| file://:0:0:0:0 | [post] self [password] | semmle.label | [post] self [password] |
|
||||
| file://:0:0:0:0 | [post] self [value] | semmle.label | [post] self [value] |
|
||||
@@ -415,6 +421,7 @@ nodes
|
||||
| file://:0:0:0:0 | value | semmle.label | value |
|
||||
| file://:0:0:0:0 | value | semmle.label | value |
|
||||
| file://:0:0:0:0 | value | semmle.label | value |
|
||||
| file://:0:0:0:0 | value | semmle.label | value |
|
||||
| sqlite3_c_api.swift:42:69:42:69 | medicalNotes | semmle.label | medicalNotes |
|
||||
| sqlite3_c_api.swift:43:49:43:49 | medicalNotes | semmle.label | medicalNotes |
|
||||
| sqlite3_c_api.swift:46:27:46:27 | insertQuery | semmle.label | insertQuery |
|
||||
@@ -701,6 +708,10 @@ nodes
|
||||
| testGRDB.swift:212:98:212:107 | [...] | semmle.label | [...] |
|
||||
| testGRDB.swift:212:98:212:107 | [...] [Collection element] | semmle.label | [...] [Collection element] |
|
||||
| testGRDB.swift:212:99:212:99 | password | semmle.label | password |
|
||||
| testRealm2.swift:13:6:13:6 | value | semmle.label | value |
|
||||
| testRealm2.swift:18:2:18:2 | [post] o | semmle.label | [post] o |
|
||||
| testRealm2.swift:18:2:18:2 | [post] o [data] | semmle.label | [post] o [data] |
|
||||
| testRealm2.swift:18:11:18:11 | myPassword | semmle.label | myPassword |
|
||||
| testRealm.swift:27:6:27:6 | value | semmle.label | value |
|
||||
| testRealm.swift:34:6:34:6 | value | semmle.label | value |
|
||||
| testRealm.swift:41:2:41:2 | [post] a | semmle.label | [post] a |
|
||||
@@ -733,6 +744,7 @@ subpaths
|
||||
| testCoreData2.swift:98:18:98:18 | d [value] | testCoreData2.swift:70:9:70:9 | self [value] | file://:0:0:0:0 | .value | testCoreData2.swift:98:18:98:20 | .value |
|
||||
| testCoreData2.swift:104:18:104:18 | e | testCoreData2.swift:70:9:70:9 | self | file://:0:0:0:0 | .value | testCoreData2.swift:104:18:104:20 | .value |
|
||||
| testCoreData2.swift:105:18:105:18 | e | testCoreData2.swift:71:9:71:9 | self | file://:0:0:0:0 | .value2 | testCoreData2.swift:105:18:105:20 | .value2 |
|
||||
| testRealm2.swift:18:11:18:11 | myPassword | testRealm2.swift:13:6:13:6 | value | file://:0:0:0:0 | [post] self [data] | testRealm2.swift:18:2:18:2 | [post] o [data] |
|
||||
| testRealm.swift:41:11:41:11 | myPassword | testRealm.swift:27:6:27:6 | value | file://:0:0:0:0 | [post] self [data] | testRealm.swift:41:2:41:2 | [post] a [data] |
|
||||
| testRealm.swift:49:11:49:11 | myPassword | testRealm.swift:27:6:27:6 | value | file://:0:0:0:0 | [post] self [data] | testRealm.swift:49:2:49:2 | [post] c [data] |
|
||||
| testRealm.swift:59:12:59:12 | myPassword | testRealm.swift:27:6:27:6 | value | file://:0:0:0:0 | [post] self [data] | testRealm.swift:59:2:59:3 | [post] ...! [data] |
|
||||
@@ -864,6 +876,7 @@ subpaths
|
||||
| testGRDB.swift:208:80:208:89 | [...] | testGRDB.swift:208:81:208:81 | password | testGRDB.swift:208:80:208:89 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:208:81:208:81 | password | password |
|
||||
| testGRDB.swift:210:84:210:93 | [...] | testGRDB.swift:210:85:210:85 | password | testGRDB.swift:210:84:210:93 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:210:85:210:85 | password | password |
|
||||
| testGRDB.swift:212:98:212:107 | [...] | testGRDB.swift:212:99:212:99 | password | testGRDB.swift:212:98:212:107 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:212:99:212:99 | password | password |
|
||||
| testRealm2.swift:18:2:18:2 | o | testRealm2.swift:18:11:18:11 | myPassword | testRealm2.swift:18:2:18:2 | [post] o | This operation stores 'o' in a database. It may contain unencrypted sensitive data from $@. | testRealm2.swift:18:11:18:11 | myPassword | myPassword |
|
||||
| testRealm.swift:41:2:41:2 | a | testRealm.swift:41:11:41:11 | myPassword | testRealm.swift:41:2:41:2 | [post] a | This operation stores 'a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:41:11:41:11 | myPassword | myPassword |
|
||||
| testRealm.swift:49:2:49:2 | c | testRealm.swift:49:11:49:11 | myPassword | testRealm.swift:49:2:49:2 | [post] c | This operation stores 'c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:49:11:49:11 | myPassword | myPassword |
|
||||
| testRealm.swift:59:2:59:3 | ...! | testRealm.swift:59:12:59:12 | myPassword | testRealm.swift:59:2:59:3 | [post] ...! | This operation stores '...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:59:12:59:12 | myPassword | myPassword |
|
||||
|
||||
@@ -15,7 +15,7 @@ class MyRealmSwiftObject3 : Object {
|
||||
|
||||
func test1(o: MyRealmSwiftObject3, myHarmless: String, myPassword : String) {
|
||||
// ...
|
||||
o.data = myPassword // BAD [NOT DETECTED]
|
||||
o.data = myPassword // BAD
|
||||
o.data = myHarmless
|
||||
// ...
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user