Add cleartext storage database sinks

This commit is contained in:
Tony Torralba
2022-12-23 17:03:40 +01:00
parent ac39aeb6b6
commit 4215a89bc8
4 changed files with 532 additions and 0 deletions

View File

@@ -56,6 +56,61 @@ class RealmStore extends Stored instanceof DataFlow::PostUpdateNode {
}
}
/**
* A `DataFlow::Node` that is an expression stored with the GRDB library.
*/
class GrdbStore extends Stored {
GrdbStore() {
exists(CallExpr call, MethodDecl method |
call.getStaticTarget() = method and
call.getArgumentWithLabel("arguments").getExpr() = this.asExpr()
|
method
.hasQualifiedName("Database",
["allStatements(sql:arguments:)", "execute(sql:arguments:)",])
or
method.hasQualifiedName("SQLRequest", "init(sql:arguments:adapter:cached:)")
or
method.hasQualifiedName("SQL", ["init(sql:arguments:)", "append(sql:arguments:)"])
or
method.hasQualifiedName("SQLStatementCursor", "init(database:sql:arguments:prepFlags:)")
or
method
.hasQualifiedName("TableRecord",
[
"select(sql:arguments:)", "select(sql:arguments:as:)", "filter(sql:arguments:)",
"order(sql:arguments:)"
])
or
method
.hasQualifiedName(["Row", "DatabaseValueConvertible", "FetchableRecord"],
[
"fetchCursor(_:sql:arguments:adapter:)", "fetchAll(_:sql:arguments:adapter:)",
"fetchSet(_:sql:arguments:adapter:)", "fetchOne(_:sql:arguments:adapter:)"
])
or
method
.hasQualifiedName("FetchableRecord",
[
"fetchCursor(_:arguments:adapter:)", "fetchAll(_:arguments:adapter:)",
"fetchSet(_:arguments:adapter:)", "fetchOne(_:arguments:adapter:)",
])
or
method.hasQualifiedName("Statement", ["execute(arguments:)"])
or
method
.hasQualifiedName("CommonTableExpression", "init(recursive:named:columns:sql:arguments:)")
)
or
exists(CallExpr call, MethodDecl method |
call.getStaticTarget() = method and
call.getArgument(0).getExpr() = this.asExpr()
|
method.hasQualifiedName("Statement", "setArguments(_:)")
)
}
}
/**
* A taint configuration from sensitive information to expressions that are
* transmitted over a network.
@@ -77,6 +132,14 @@ class CleartextStorageConfig extends TaintTracking::Configuration {
node.asExpr() instanceof EncryptedExpr
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
// Needed until we have proper content flow through arrays
exists(ArrayExpr arr |
node1.asExpr() = arr.getAnElement() and
node2.asExpr() = arr
)
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
// flow out from fields of a `RealmSwiftObject` at the sink, for example in
// `realmObj.data = sensitive`.

View File

@@ -9,6 +9,57 @@ edges
| testCoreData.swift:91:10:91:10 | passwd : | testCoreData.swift:95:15:95:15 | x |
| testCoreData.swift:92:10:92:10 | passwd : | testCoreData.swift:96:15:96:15 | y |
| testCoreData.swift:93:10:93:10 | passwd : | testCoreData.swift:97:15:97:15 | z |
| testGRDB.swift:73:57:73:57 | password : | testGRDB.swift:73:56:73:65 | [...] |
| testGRDB.swift:76:43:76:43 | password : | testGRDB.swift:76:42:76:51 | [...] |
| testGRDB.swift:81:45:81:45 | password : | testGRDB.swift:81:44:81:53 | [...] |
| testGRDB.swift:83:45:83:45 | password : | testGRDB.swift:83:44:83:53 | [...] |
| testGRDB.swift:85:45:85:45 | password : | testGRDB.swift:85:44:85:53 | [...] |
| testGRDB.swift:87:45:87:45 | password : | testGRDB.swift:87:44:87:53 | [...] |
| testGRDB.swift:92:38:92:38 | password : | testGRDB.swift:92:37:92:46 | [...] |
| testGRDB.swift:95:37:95:37 | password : | testGRDB.swift:95:36:95:45 | [...] |
| testGRDB.swift:100:73:100:73 | password : | testGRDB.swift:100:72:100:81 | [...] |
| testGRDB.swift:101:73:101:73 | password : | testGRDB.swift:101:72:101:81 | [...] |
| testGRDB.swift:107:53:107:53 | password : | testGRDB.swift:107:52:107:61 | [...] |
| testGRDB.swift:109:53:109:53 | password : | testGRDB.swift:109:52:109:61 | [...] |
| testGRDB.swift:111:52:111:52 | password : | testGRDB.swift:111:51:111:60 | [...] |
| testGRDB.swift:116:48:116:48 | password : | testGRDB.swift:116:47:116:56 | [...] |
| testGRDB.swift:118:48:118:48 | password : | testGRDB.swift:118:47:118:56 | [...] |
| testGRDB.swift:121:45:121:45 | password : | testGRDB.swift:121:44:121:53 | [...] |
| testGRDB.swift:123:45:123:45 | password : | testGRDB.swift:123:44:123:53 | [...] |
| testGRDB.swift:126:45:126:45 | password : | testGRDB.swift:126:44:126:53 | [...] |
| testGRDB.swift:128:45:128:45 | password : | testGRDB.swift:128:44:128:53 | [...] |
| testGRDB.swift:131:45:131:45 | password : | testGRDB.swift:131:44:131:53 | [...] |
| testGRDB.swift:133:45:133:45 | password : | testGRDB.swift:133:44:133:53 | [...] |
| testGRDB.swift:138:69:138:69 | password : | testGRDB.swift:138:68:138:77 | [...] |
| testGRDB.swift:140:69:140:69 | password : | testGRDB.swift:140:68:140:77 | [...] |
| testGRDB.swift:143:66:143:66 | password : | testGRDB.swift:143:65:143:74 | [...] |
| testGRDB.swift:145:66:145:66 | password : | testGRDB.swift:145:65:145:74 | [...] |
| testGRDB.swift:148:66:148:66 | password : | testGRDB.swift:148:65:148:74 | [...] |
| testGRDB.swift:150:66:150:66 | password : | testGRDB.swift:150:65:150:74 | [...] |
| testGRDB.swift:153:66:153:66 | password : | testGRDB.swift:153:65:153:74 | [...] |
| testGRDB.swift:155:66:155:66 | password : | testGRDB.swift:155:65:155:74 | [...] |
| testGRDB.swift:160:60:160:60 | password : | testGRDB.swift:160:59:160:68 | [...] |
| testGRDB.swift:161:51:161:51 | password : | testGRDB.swift:161:50:161:59 | [...] |
| testGRDB.swift:164:60:164:60 | password : | testGRDB.swift:164:59:164:68 | [...] |
| testGRDB.swift:165:51:165:51 | password : | testGRDB.swift:165:50:165:59 | [...] |
| testGRDB.swift:169:57:169:57 | password : | testGRDB.swift:169:56:169:65 | [...] |
| testGRDB.swift:170:48:170:48 | password : | testGRDB.swift:170:47:170:56 | [...] |
| testGRDB.swift:173:57:173:57 | password : | testGRDB.swift:173:56:173:65 | [...] |
| testGRDB.swift:174:48:174:48 | password : | testGRDB.swift:174:47:174:56 | [...] |
| testGRDB.swift:178:57:178:57 | password : | testGRDB.swift:178:56:178:65 | [...] |
| testGRDB.swift:179:48:179:48 | password : | testGRDB.swift:179:47:179:56 | [...] |
| testGRDB.swift:182:57:182:57 | password : | testGRDB.swift:182:56:182:65 | [...] |
| testGRDB.swift:183:48:183:48 | password : | testGRDB.swift:183:47:183:56 | [...] |
| testGRDB.swift:187:57:187:57 | password : | testGRDB.swift:187:56:187:65 | [...] |
| testGRDB.swift:188:48:188:48 | password : | testGRDB.swift:188:47:188:56 | [...] |
| testGRDB.swift:191:57:191:57 | password : | testGRDB.swift:191:56:191:65 | [...] |
| testGRDB.swift:192:48:192:48 | password : | testGRDB.swift:192:47:192:56 | [...] |
| testGRDB.swift:198:30:198:30 | password : | testGRDB.swift:198:29:198:38 | [...] |
| testGRDB.swift:201:24:201:24 | password : | testGRDB.swift:201:23:201:32 | [...] |
| testGRDB.swift:206:67:206:67 | password : | testGRDB.swift:206:66:206:75 | [...] |
| testGRDB.swift:208:81:208:81 | password : | testGRDB.swift:208:80:208:89 | [...] |
| testGRDB.swift:210:85:210:85 | password : | testGRDB.swift:210:84:210:93 | [...] |
| testGRDB.swift:212:99:212:99 | password : | testGRDB.swift:212:98:212:107 | [...] |
| testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | value : |
| testRealm.swift:34:2:34:2 | [post] a [data] : | testRealm.swift:34:2:34:2 | [post] a |
| testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:16:6:16:6 | value : |
@@ -45,6 +96,108 @@ nodes
| testCoreData.swift:95:15:95:15 | x | semmle.label | x |
| testCoreData.swift:96:15:96:15 | y | semmle.label | y |
| testCoreData.swift:97:15:97:15 | z | semmle.label | z |
| testGRDB.swift:73:56:73:65 | [...] | semmle.label | [...] |
| testGRDB.swift:73:57:73:57 | password : | semmle.label | password : |
| testGRDB.swift:76:42:76:51 | [...] | semmle.label | [...] |
| testGRDB.swift:76:43:76:43 | password : | semmle.label | password : |
| testGRDB.swift:81:44:81:53 | [...] | semmle.label | [...] |
| testGRDB.swift:81:45:81:45 | password : | semmle.label | password : |
| testGRDB.swift:83:44:83:53 | [...] | semmle.label | [...] |
| testGRDB.swift:83:45:83:45 | password : | semmle.label | password : |
| testGRDB.swift:85:44:85:53 | [...] | semmle.label | [...] |
| testGRDB.swift:85:45:85:45 | password : | semmle.label | password : |
| testGRDB.swift:87:44:87:53 | [...] | semmle.label | [...] |
| testGRDB.swift:87:45:87:45 | password : | semmle.label | password : |
| testGRDB.swift:92:37:92:46 | [...] | semmle.label | [...] |
| testGRDB.swift:92:38:92:38 | password : | semmle.label | password : |
| testGRDB.swift:95:36:95:45 | [...] | semmle.label | [...] |
| testGRDB.swift:95:37:95:37 | password : | semmle.label | password : |
| testGRDB.swift:100:72:100:81 | [...] | semmle.label | [...] |
| testGRDB.swift:100:73:100:73 | password : | semmle.label | password : |
| testGRDB.swift:101:72:101:81 | [...] | semmle.label | [...] |
| testGRDB.swift:101:73:101:73 | password : | semmle.label | password : |
| testGRDB.swift:107:52:107:61 | [...] | semmle.label | [...] |
| testGRDB.swift:107:53:107:53 | password : | semmle.label | password : |
| testGRDB.swift:109:52:109:61 | [...] | semmle.label | [...] |
| testGRDB.swift:109:53:109:53 | password : | semmle.label | password : |
| testGRDB.swift:111:51:111:60 | [...] | semmle.label | [...] |
| testGRDB.swift:111:52:111:52 | password : | semmle.label | password : |
| testGRDB.swift:116:47:116:56 | [...] | semmle.label | [...] |
| testGRDB.swift:116:48:116:48 | password : | semmle.label | password : |
| testGRDB.swift:118:47:118:56 | [...] | semmle.label | [...] |
| testGRDB.swift:118:48:118:48 | password : | semmle.label | password : |
| testGRDB.swift:121:44:121:53 | [...] | semmle.label | [...] |
| testGRDB.swift:121:45:121:45 | password : | semmle.label | password : |
| testGRDB.swift:123:44:123:53 | [...] | semmle.label | [...] |
| testGRDB.swift:123:45:123:45 | password : | semmle.label | password : |
| testGRDB.swift:126:44:126:53 | [...] | semmle.label | [...] |
| testGRDB.swift:126:45:126:45 | password : | semmle.label | password : |
| testGRDB.swift:128:44:128:53 | [...] | semmle.label | [...] |
| testGRDB.swift:128:45:128:45 | password : | semmle.label | password : |
| testGRDB.swift:131:44:131:53 | [...] | semmle.label | [...] |
| testGRDB.swift:131:45:131:45 | password : | semmle.label | password : |
| testGRDB.swift:133:44:133:53 | [...] | semmle.label | [...] |
| testGRDB.swift:133:45:133:45 | password : | semmle.label | password : |
| testGRDB.swift:138:68:138:77 | [...] | semmle.label | [...] |
| testGRDB.swift:138:69:138:69 | password : | semmle.label | password : |
| testGRDB.swift:140:68:140:77 | [...] | semmle.label | [...] |
| testGRDB.swift:140:69:140:69 | password : | semmle.label | password : |
| testGRDB.swift:143:65:143:74 | [...] | semmle.label | [...] |
| testGRDB.swift:143:66:143:66 | password : | semmle.label | password : |
| testGRDB.swift:145:65:145:74 | [...] | semmle.label | [...] |
| testGRDB.swift:145:66:145:66 | password : | semmle.label | password : |
| testGRDB.swift:148:65:148:74 | [...] | semmle.label | [...] |
| testGRDB.swift:148:66:148:66 | password : | semmle.label | password : |
| testGRDB.swift:150:65:150:74 | [...] | semmle.label | [...] |
| testGRDB.swift:150:66:150:66 | password : | semmle.label | password : |
| testGRDB.swift:153:65:153:74 | [...] | semmle.label | [...] |
| testGRDB.swift:153:66:153:66 | password : | semmle.label | password : |
| testGRDB.swift:155:65:155:74 | [...] | semmle.label | [...] |
| testGRDB.swift:155:66:155:66 | password : | semmle.label | password : |
| testGRDB.swift:160:59:160:68 | [...] | semmle.label | [...] |
| testGRDB.swift:160:60:160:60 | password : | semmle.label | password : |
| testGRDB.swift:161:50:161:59 | [...] | semmle.label | [...] |
| testGRDB.swift:161:51:161:51 | password : | semmle.label | password : |
| testGRDB.swift:164:59:164:68 | [...] | semmle.label | [...] |
| testGRDB.swift:164:60:164:60 | password : | semmle.label | password : |
| testGRDB.swift:165:50:165:59 | [...] | semmle.label | [...] |
| testGRDB.swift:165:51:165:51 | password : | semmle.label | password : |
| testGRDB.swift:169:56:169:65 | [...] | semmle.label | [...] |
| testGRDB.swift:169:57:169:57 | password : | semmle.label | password : |
| testGRDB.swift:170:47:170:56 | [...] | semmle.label | [...] |
| testGRDB.swift:170:48:170:48 | password : | semmle.label | password : |
| testGRDB.swift:173:56:173:65 | [...] | semmle.label | [...] |
| testGRDB.swift:173:57:173:57 | password : | semmle.label | password : |
| testGRDB.swift:174:47:174:56 | [...] | semmle.label | [...] |
| testGRDB.swift:174:48:174:48 | password : | semmle.label | password : |
| testGRDB.swift:178:56:178:65 | [...] | semmle.label | [...] |
| testGRDB.swift:178:57:178:57 | password : | semmle.label | password : |
| testGRDB.swift:179:47:179:56 | [...] | semmle.label | [...] |
| testGRDB.swift:179:48:179:48 | password : | semmle.label | password : |
| testGRDB.swift:182:56:182:65 | [...] | semmle.label | [...] |
| testGRDB.swift:182:57:182:57 | password : | semmle.label | password : |
| testGRDB.swift:183:47:183:56 | [...] | semmle.label | [...] |
| testGRDB.swift:183:48:183:48 | password : | semmle.label | password : |
| testGRDB.swift:187:56:187:65 | [...] | semmle.label | [...] |
| testGRDB.swift:187:57:187:57 | password : | semmle.label | password : |
| testGRDB.swift:188:47:188:56 | [...] | semmle.label | [...] |
| testGRDB.swift:188:48:188:48 | password : | semmle.label | password : |
| testGRDB.swift:191:56:191:65 | [...] | semmle.label | [...] |
| testGRDB.swift:191:57:191:57 | password : | semmle.label | password : |
| testGRDB.swift:192:47:192:56 | [...] | semmle.label | [...] |
| testGRDB.swift:192:48:192:48 | password : | semmle.label | password : |
| testGRDB.swift:198:29:198:38 | [...] | semmle.label | [...] |
| testGRDB.swift:198:30:198:30 | password : | semmle.label | password : |
| testGRDB.swift:201:23:201:32 | [...] | semmle.label | [...] |
| testGRDB.swift:201:24:201:24 | password : | semmle.label | password : |
| testGRDB.swift:206:66:206:75 | [...] | semmle.label | [...] |
| testGRDB.swift:206:67:206:67 | password : | semmle.label | password : |
| testGRDB.swift:208:80:208:89 | [...] | semmle.label | [...] |
| testGRDB.swift:208:81:208:81 | password : | semmle.label | password : |
| testGRDB.swift:210:84:210:93 | [...] | semmle.label | [...] |
| testGRDB.swift:210:85:210:85 | password : | semmle.label | password : |
| testGRDB.swift:212:98:212:107 | [...] | semmle.label | [...] |
| testGRDB.swift:212:99:212:99 | password : | semmle.label | password : |
| testRealm.swift:16:6:16:6 | value : | semmle.label | value : |
| testRealm.swift:34:2:34:2 | [post] a | semmle.label | [post] a |
| testRealm.swift:34:2:34:2 | [post] a [data] : | semmle.label | [post] a [data] : |
@@ -75,6 +228,57 @@ subpaths
| 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 |
| 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 |
| 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 |
| testGRDB.swift:73:56:73:65 | [...] | testGRDB.swift:73:57:73:57 | password : | testGRDB.swift:73:56:73:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:73:57:73:57 | password : | password |
| testGRDB.swift:76:42:76:51 | [...] | testGRDB.swift:76:43:76:43 | password : | testGRDB.swift:76:42:76:51 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:76:43:76:43 | password : | password |
| testGRDB.swift:81:44:81:53 | [...] | testGRDB.swift:81:45:81:45 | password : | testGRDB.swift:81:44:81:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:81:45:81:45 | password : | password |
| testGRDB.swift:83:44:83:53 | [...] | testGRDB.swift:83:45:83:45 | password : | testGRDB.swift:83:44:83:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:83:45:83:45 | password : | password |
| testGRDB.swift:85:44:85:53 | [...] | testGRDB.swift:85:45:85:45 | password : | testGRDB.swift:85:44:85:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:85:45:85:45 | password : | password |
| testGRDB.swift:87:44:87:53 | [...] | testGRDB.swift:87:45:87:45 | password : | testGRDB.swift:87:44:87:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:87:45:87:45 | password : | password |
| testGRDB.swift:92:37:92:46 | [...] | testGRDB.swift:92:38:92:38 | password : | testGRDB.swift:92:37:92:46 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:92:38:92:38 | password : | password |
| testGRDB.swift:95:36:95:45 | [...] | testGRDB.swift:95:37:95:37 | password : | testGRDB.swift:95:36:95:45 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:95:37:95:37 | password : | password |
| testGRDB.swift:100:72:100:81 | [...] | testGRDB.swift:100:73:100:73 | password : | testGRDB.swift:100:72:100:81 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:100:73:100:73 | password : | password |
| testGRDB.swift:101:72:101:81 | [...] | testGRDB.swift:101:73:101:73 | password : | testGRDB.swift:101:72:101:81 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:101:73:101:73 | password : | password |
| testGRDB.swift:107:52:107:61 | [...] | testGRDB.swift:107:53:107:53 | password : | testGRDB.swift:107:52:107:61 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:107:53:107:53 | password : | password |
| testGRDB.swift:109:52:109:61 | [...] | testGRDB.swift:109:53:109:53 | password : | testGRDB.swift:109:52:109:61 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:109:53:109:53 | password : | password |
| testGRDB.swift:111:51:111:60 | [...] | testGRDB.swift:111:52:111:52 | password : | testGRDB.swift:111:51:111:60 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:111:52:111:52 | password : | password |
| testGRDB.swift:116:47:116:56 | [...] | testGRDB.swift:116:48:116:48 | password : | testGRDB.swift:116:47:116:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:116:48:116:48 | password : | password |
| testGRDB.swift:118:47:118:56 | [...] | testGRDB.swift:118:48:118:48 | password : | testGRDB.swift:118:47:118:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:118:48:118:48 | password : | password |
| testGRDB.swift:121:44:121:53 | [...] | testGRDB.swift:121:45:121:45 | password : | testGRDB.swift:121:44:121:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:121:45:121:45 | password : | password |
| testGRDB.swift:123:44:123:53 | [...] | testGRDB.swift:123:45:123:45 | password : | testGRDB.swift:123:44:123:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:123:45:123:45 | password : | password |
| testGRDB.swift:126:44:126:53 | [...] | testGRDB.swift:126:45:126:45 | password : | testGRDB.swift:126:44:126:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:126:45:126:45 | password : | password |
| testGRDB.swift:128:44:128:53 | [...] | testGRDB.swift:128:45:128:45 | password : | testGRDB.swift:128:44:128:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:128:45:128:45 | password : | password |
| testGRDB.swift:131:44:131:53 | [...] | testGRDB.swift:131:45:131:45 | password : | testGRDB.swift:131:44:131:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:131:45:131:45 | password : | password |
| testGRDB.swift:133:44:133:53 | [...] | testGRDB.swift:133:45:133:45 | password : | testGRDB.swift:133:44:133:53 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:133:45:133:45 | password : | password |
| testGRDB.swift:138:68:138:77 | [...] | testGRDB.swift:138:69:138:69 | password : | testGRDB.swift:138:68:138:77 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:138:69:138:69 | password : | password |
| testGRDB.swift:140:68:140:77 | [...] | testGRDB.swift:140:69:140:69 | password : | testGRDB.swift:140:68:140:77 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:140:69:140:69 | password : | password |
| testGRDB.swift:143:65:143:74 | [...] | testGRDB.swift:143:66:143:66 | password : | testGRDB.swift:143:65:143:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:143:66:143:66 | password : | password |
| testGRDB.swift:145:65:145:74 | [...] | testGRDB.swift:145:66:145:66 | password : | testGRDB.swift:145:65:145:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:145:66:145:66 | password : | password |
| testGRDB.swift:148:65:148:74 | [...] | testGRDB.swift:148:66:148:66 | password : | testGRDB.swift:148:65:148:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:148:66:148:66 | password : | password |
| testGRDB.swift:150:65:150:74 | [...] | testGRDB.swift:150:66:150:66 | password : | testGRDB.swift:150:65:150:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:150:66:150:66 | password : | password |
| testGRDB.swift:153:65:153:74 | [...] | testGRDB.swift:153:66:153:66 | password : | testGRDB.swift:153:65:153:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:153:66:153:66 | password : | password |
| testGRDB.swift:155:65:155:74 | [...] | testGRDB.swift:155:66:155:66 | password : | testGRDB.swift:155:65:155:74 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:155:66:155:66 | password : | password |
| testGRDB.swift:160:59:160:68 | [...] | testGRDB.swift:160:60:160:60 | password : | testGRDB.swift:160:59:160:68 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:160:60:160:60 | password : | password |
| testGRDB.swift:161:50:161:59 | [...] | testGRDB.swift:161:51:161:51 | password : | testGRDB.swift:161:50:161:59 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:161:51:161:51 | password : | password |
| testGRDB.swift:164:59:164:68 | [...] | testGRDB.swift:164:60:164:60 | password : | testGRDB.swift:164:59:164:68 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:164:60:164:60 | password : | password |
| testGRDB.swift:165:50:165:59 | [...] | testGRDB.swift:165:51:165:51 | password : | testGRDB.swift:165:50:165:59 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:165:51:165:51 | password : | password |
| testGRDB.swift:169:56:169:65 | [...] | testGRDB.swift:169:57:169:57 | password : | testGRDB.swift:169:56:169:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:169:57:169:57 | password : | password |
| testGRDB.swift:170:47:170:56 | [...] | testGRDB.swift:170:48:170:48 | password : | testGRDB.swift:170:47:170:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:170:48:170:48 | password : | password |
| testGRDB.swift:173:56:173:65 | [...] | testGRDB.swift:173:57:173:57 | password : | testGRDB.swift:173:56:173:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:173:57:173:57 | password : | password |
| testGRDB.swift:174:47:174:56 | [...] | testGRDB.swift:174:48:174:48 | password : | testGRDB.swift:174:47:174:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:174:48:174:48 | password : | password |
| testGRDB.swift:178:56:178:65 | [...] | testGRDB.swift:178:57:178:57 | password : | testGRDB.swift:178:56:178:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:178:57:178:57 | password : | password |
| testGRDB.swift:179:47:179:56 | [...] | testGRDB.swift:179:48:179:48 | password : | testGRDB.swift:179:47:179:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:179:48:179:48 | password : | password |
| testGRDB.swift:182:56:182:65 | [...] | testGRDB.swift:182:57:182:57 | password : | testGRDB.swift:182:56:182:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:182:57:182:57 | password : | password |
| testGRDB.swift:183:47:183:56 | [...] | testGRDB.swift:183:48:183:48 | password : | testGRDB.swift:183:47:183:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:183:48:183:48 | password : | password |
| testGRDB.swift:187:56:187:65 | [...] | testGRDB.swift:187:57:187:57 | password : | testGRDB.swift:187:56:187:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:187:57:187:57 | password : | password |
| testGRDB.swift:188:47:188:56 | [...] | testGRDB.swift:188:48:188:48 | password : | testGRDB.swift:188:47:188:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:188:48:188:48 | password : | password |
| testGRDB.swift:191:56:191:65 | [...] | testGRDB.swift:191:57:191:57 | password : | testGRDB.swift:191:56:191:65 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:191:57:191:57 | password : | password |
| testGRDB.swift:192:47:192:56 | [...] | testGRDB.swift:192:48:192:48 | password : | testGRDB.swift:192:47:192:56 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:192:48:192:48 | password : | password |
| testGRDB.swift:198:29:198:38 | [...] | testGRDB.swift:198:30:198:30 | password : | testGRDB.swift:198:29:198:38 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:198:30:198:30 | password : | password |
| testGRDB.swift:201:23:201:32 | [...] | testGRDB.swift:201:24:201:24 | password : | testGRDB.swift:201:23:201:32 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:201:24:201:24 | password : | password |
| testGRDB.swift:206:66:206:75 | [...] | testGRDB.swift:206:67:206:67 | password : | testGRDB.swift:206:66:206:75 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:206:67:206:67 | password : | password |
| 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 |
| testRealm.swift:34:2:34:2 | a | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:34:2:34:2 | [post] a | This operation stores '[post] a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:34:11:34:11 | myPassword : | myPassword |
| testRealm.swift:42:2:42:2 | c | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:42:2:42:2 | [post] c | This operation stores '[post] c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:42:11:42:11 | myPassword : | myPassword |
| testRealm.swift:52:2:52:3 | ...! | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:52:2:52:3 | [post] ...! | This operation stores '[post] ...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:52:12:52:12 | myPassword : | myPassword |

View File

@@ -20,6 +20,57 @@
| testCoreData.swift:91:10:91:10 | passwd | label:passwd, type:credential |
| testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential |
| testCoreData.swift:93:10:93:10 | passwd | label:passwd, type:credential |
| testGRDB.swift:73:57:73:57 | password | label:password, type:credential |
| testGRDB.swift:76:43:76:43 | password | label:password, type:credential |
| testGRDB.swift:81:45:81:45 | password | label:password, type:credential |
| testGRDB.swift:83:45:83:45 | password | label:password, type:credential |
| testGRDB.swift:85:45:85:45 | password | label:password, type:credential |
| testGRDB.swift:87:45:87:45 | password | label:password, type:credential |
| testGRDB.swift:92:38:92:38 | password | label:password, type:credential |
| testGRDB.swift:95:37:95:37 | password | label:password, type:credential |
| testGRDB.swift:100:73:100:73 | password | label:password, type:credential |
| testGRDB.swift:101:73:101:73 | password | label:password, type:credential |
| testGRDB.swift:107:53:107:53 | password | label:password, type:credential |
| testGRDB.swift:109:53:109:53 | password | label:password, type:credential |
| testGRDB.swift:111:52:111:52 | password | label:password, type:credential |
| testGRDB.swift:116:48:116:48 | password | label:password, type:credential |
| testGRDB.swift:118:48:118:48 | password | label:password, type:credential |
| testGRDB.swift:121:45:121:45 | password | label:password, type:credential |
| testGRDB.swift:123:45:123:45 | password | label:password, type:credential |
| testGRDB.swift:126:45:126:45 | password | label:password, type:credential |
| testGRDB.swift:128:45:128:45 | password | label:password, type:credential |
| testGRDB.swift:131:45:131:45 | password | label:password, type:credential |
| testGRDB.swift:133:45:133:45 | password | label:password, type:credential |
| testGRDB.swift:138:69:138:69 | password | label:password, type:credential |
| testGRDB.swift:140:69:140:69 | password | label:password, type:credential |
| testGRDB.swift:143:66:143:66 | password | label:password, type:credential |
| testGRDB.swift:145:66:145:66 | password | label:password, type:credential |
| testGRDB.swift:148:66:148:66 | password | label:password, type:credential |
| testGRDB.swift:150:66:150:66 | password | label:password, type:credential |
| testGRDB.swift:153:66:153:66 | password | label:password, type:credential |
| testGRDB.swift:155:66:155:66 | password | label:password, type:credential |
| testGRDB.swift:160:60:160:60 | password | label:password, type:credential |
| testGRDB.swift:161:51:161:51 | password | label:password, type:credential |
| testGRDB.swift:164:60:164:60 | password | label:password, type:credential |
| testGRDB.swift:165:51:165:51 | password | label:password, type:credential |
| testGRDB.swift:169:57:169:57 | password | label:password, type:credential |
| testGRDB.swift:170:48:170:48 | password | label:password, type:credential |
| testGRDB.swift:173:57:173:57 | password | label:password, type:credential |
| testGRDB.swift:174:48:174:48 | password | label:password, type:credential |
| testGRDB.swift:178:57:178:57 | password | label:password, type:credential |
| testGRDB.swift:179:48:179:48 | password | label:password, type:credential |
| testGRDB.swift:182:57:182:57 | password | label:password, type:credential |
| testGRDB.swift:183:48:183:48 | password | label:password, type:credential |
| testGRDB.swift:187:57:187:57 | password | label:password, type:credential |
| testGRDB.swift:188:48:188:48 | password | label:password, type:credential |
| testGRDB.swift:191:57:191:57 | password | label:password, type:credential |
| testGRDB.swift:192:48:192:48 | password | label:password, type:credential |
| testGRDB.swift:198:30:198:30 | password | label:password, type:credential |
| testGRDB.swift:201:24:201:24 | password | label:password, type:credential |
| testGRDB.swift:206:67:206:67 | password | label:password, type:credential |
| testGRDB.swift:208:81:208:81 | password | label:password, type:credential |
| testGRDB.swift:210:85:210:85 | password | label:password, type:credential |
| testGRDB.swift:212:99:212:99 | password | label:password, type:credential |
| testRealm.swift:34:11:34:11 | myPassword | label:myPassword, type:credential |
| testRealm.swift:42:11:42:11 | myPassword | label:myPassword, type:credential |
| testRealm.swift:52:12:52:12 | myPassword | label:myPassword, type:credential |

View File

@@ -0,0 +1,214 @@
// --- stubs ---
struct StatementArguments : ExpressibleByArrayLiteral {
init(arrayLiteral: (String)?...) {}
}
protocol RowAdapter {}
struct QueryInterfaceRequest<T> {}
class Database {
func allStatements(sql: String, arguments: StatementArguments? = nil) -> SQLStatementCursor { return SQLStatementCursor(database: self, sql: "", arguments: nil) }
func execute(sql: String, arguments: StatementArguments = StatementArguments()) {}
}
class SQLRequest {
init(sql: String, arguments: StatementArguments = StatementArguments(), adapter: (any RowAdapter)? = nil, cached: Bool = false) {}
}
class SQL {
init(sql: String, arguments: StatementArguments = StatementArguments()) {}
func append(sql: String, arguments: StatementArguments = StatementArguments()) {}
}
class SQLStatementCursor {
init(database: Database, sql: String, arguments: StatementArguments?, prepFlags: CUnsignedInt = 0) {}
}
class TableRecord {
static func select(sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<TableRecord> { QueryInterfaceRequest<TableRecord>() }
static func select<RowDecoder>(sql: String, arguments: StatementArguments = StatementArguments(), as: RowDecoder.Type = RowDecoder.self) -> QueryInterfaceRequest<TableRecord>{ QueryInterfaceRequest<TableRecord>() }
static func filter(sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<TableRecord> { QueryInterfaceRequest<TableRecord>() }
static func order(sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<TableRecord> { QueryInterfaceRequest<TableRecord>() }
}
class Row {
func fetchCursor(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchAll(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchSet(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchOne(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
}
class DatabaseValueConvertible {
func fetchCursor(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchAll(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchSet(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchOne(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
}
class FetchableRecord {
func fetchCursor(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchCursor(_: Statement, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchAll(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchAll(_: Statement, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchSet(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchSet(_: Statement, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchOne(_: Statement, sql: String, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
func fetchOne(_: Statement, arguments: StatementArguments? = nil, adapter: (any RowAdapter)? = nil) {}
}
class Statement {
func execute(arguments: StatementArguments? = nil) {}
func setArguments(_: StatementArguments) {}
}
class CommonTableExpression {
init(recursive: Bool = false, named: String, columns: [String]? = nil, sql: String, arguments: StatementArguments = StatementArguments()) {}
}
// --- tests ---
func test(database: Database, password: String, harmless: String) {
let _ = database.allStatements(sql: "", arguments: [password]) // BAD
let _ = database.allStatements(sql: "", arguments: [harmless]) // GOOD
database.execute(sql: "", arguments: [password]) // BAD
database.execute(sql: "", arguments: [harmless]) // GOOD
}
func testSqlRequest(password: String, harmless: String) {
let _ = SQLRequest(sql: "", arguments: [password]) // BAD
let _ = SQLRequest(sql: "", arguments: [harmless]) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil) // BAD
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], cached: false) // BAD
let _ = SQLRequest(sql: "", arguments: [harmless], cached: false) // GOOD
let _ = SQLRequest(sql: "", arguments: [password], adapter: nil, cached: false) // BAD
let _ = SQLRequest(sql: "", arguments: [harmless], adapter: nil, cached: false) // GOOD
}
func test(sql: SQL, password: String, harmless: String) {
let _ = SQL(sql: "", arguments: [password]) // BAD
let _ = SQL(sql: "", arguments: [harmless]) // GOOD
sql.append(sql: "", arguments: [password]) // BAD
sql.append(sql: "", arguments: [harmless]) // GOOD
}
func testSqlStatementCursor(database: Database, password: String, harmless: String) {
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password]) // BAD
let _ = SQLStatementCursor(database: database, sql: "", arguments: [password], prepFlags: 0) // BAD
let _ = SQLStatementCursor(database: database, sql: "", arguments: [harmless]) // GOOD
let _ = SQLStatementCursor(database: database, sql: "", arguments: [harmless], prepFlags: 0) // GOOD
}
func testTableRecord(password: String, harmless: String) {
let _ = TableRecord.select(sql: "", arguments: [password]) // BAD
let _ = TableRecord.select(sql: "", arguments: [harmless]) // GOOD
let _ = TableRecord.filter(sql: "", arguments: [password]) // BAD
let _ = TableRecord.filter(sql: "", arguments: [harmless]) // GOOD
let _ = TableRecord.order(sql: "", arguments: [password]) // BAD
let _ = TableRecord.order(sql: "", arguments: [harmless]) // GOOD
}
func test(row: Row, stmt: Statement, password: String, harmless: String) {
row.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
row.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchAll(stmt, sql: "", arguments: [password]) // BAD
row.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchSet(stmt, sql: "", arguments: [password]) // BAD
row.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
row.fetchOne(stmt, sql: "", arguments: [password]) // BAD
row.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
row.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
row.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
}
func test(databaseValueConvertible: DatabaseValueConvertible, stmt: Statement, password: String, harmless: String) {
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password]) // BAD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
databaseValueConvertible.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
}
func test(fetchableRecord: FetchableRecord, stmt: Statement, password: String, harmless: String) {
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchCursor(stmt, arguments: [password]) // BAD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchCursor(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchCursor(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchCursor(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchCursor(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchAll(stmt, arguments: [password]) // BAD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchAll(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchAll(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchAll(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchAll(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchSet(stmt, arguments: [password]) // BAD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchSet(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchSet(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchSet(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchSet(stmt, arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password]) // BAD
fetchableRecord.fetchOne(stmt, arguments: [password]) // BAD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [harmless]) // GOOD
fetchableRecord.fetchOne(stmt, arguments: [harmless]) // GOOD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchOne(stmt, arguments: [password], adapter: nil) // BAD
fetchableRecord.fetchOne(stmt, sql: "", arguments: [harmless], adapter: nil) // GOOD
fetchableRecord.fetchOne(stmt, arguments: [harmless], adapter: nil) // GOOD
}
func test(stmt: Statement, password: String, harmless: String) {
stmt.execute(arguments: [password]) // BAD
stmt.execute(arguments: [harmless]) // GOOD
stmt.setArguments([password]) // BAD
stmt.setArguments([harmless]) // GOOD
}
func testCommonTableExpression(password: String, harmless: String) {
let _ = CommonTableExpression(named: "", sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(named: "", sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(recursive: false, named: "", sql: "", arguments: [harmless]) // GOOD
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [password]) // BAD
let _ = CommonTableExpression(recursive: false, named: "", columns: nil, sql: "", arguments: [harmless]) // GOOD
}