diff --git a/swift/ql/lib/change-notes/2023-10-16-collection-content.md b/swift/ql/lib/change-notes/2023-10-16-collection-content.md new file mode 100644 index 00000000000..c2e50f53dcf --- /dev/null +++ b/swift/ql/lib/change-notes/2023-10-16-collection-content.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +* Collection content is now automatically read at taint flow sinks. This removes the need to define an `allowImplicitRead` predicate on data flow configurations where the sink might be an array, set or similar type with tainted contents. Where that step had not been defined, taint may find additional results now. diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPublic.qll index b469ffa82a4..833b0583c16 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPublic.qll @@ -37,4 +37,9 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet cs) cx.asNominalTypeDecl() = d and cs.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember() ) + or + // We often expect taint to reach a sink inside `CollectionContent`, for example an array element + // or pointer contents. It is convenient to have a default implicit read step for these cases rather + // than implementing this step in a lot of separate `allowImplicitRead`s. + cs.getAReadContent() instanceof DataFlow::Content::CollectionContent } diff --git a/swift/ql/lib/codeql/swift/security/CleartextLoggingQuery.qll b/swift/ql/lib/codeql/swift/security/CleartextLoggingQuery.qll index b5d3217e483..740fccefe97 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextLoggingQuery.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextLoggingQuery.qll @@ -25,12 +25,6 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { any(CleartextLoggingAdditionalFlowStep s).step(n1, n2) } - - predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - // flow out from collection content at the sink. - isSink(node) and - c.getAReadContent() instanceof DataFlow::Content::CollectionContent - } } /** diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll index 7778924f330..25f595a8dd2 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll @@ -45,11 +45,6 @@ module CleartextStorageDatabaseConfig implements DataFlow::ConfigSig { isSink(node) and node.asExpr().getType().getUnderlyingType() instanceof DictionaryType and c.getAReadContent().(DataFlow::Content::TupleContent).getIndex() = 1 - or - // flow out from array elements (and other collection content) at the sink, - // for example in `database.allStatements(sql: "", arguments: [sensitive])`. - isSink(node) and - c.getAReadContent() instanceof DataFlow::Content::CollectionContent } } diff --git a/swift/ql/lib/codeql/swift/security/CommandInjectionQuery.qll b/swift/ql/lib/codeql/swift/security/CommandInjectionQuery.qll index c99332038b4..10dbc137726 100644 --- a/swift/ql/lib/codeql/swift/security/CommandInjectionQuery.qll +++ b/swift/ql/lib/codeql/swift/security/CommandInjectionQuery.qll @@ -23,12 +23,6 @@ module CommandInjectionConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(CommandInjectionAdditionalFlowStep s).step(nodeFrom, nodeTo) } - - predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - // flow out from array elements of at the sink, for example in `task.arguments = [tainted]`. - isSink(node) and - c.getAReadContent() instanceof DataFlow::Content::CollectionContent - } } /** diff --git a/swift/ql/lib/codeql/swift/security/ConstantPasswordQuery.qll b/swift/ql/lib/codeql/swift/security/ConstantPasswordQuery.qll index f4c024eadda..7f6475a6ee4 100644 --- a/swift/ql/lib/codeql/swift/security/ConstantPasswordQuery.qll +++ b/swift/ql/lib/codeql/swift/security/ConstantPasswordQuery.qll @@ -30,6 +30,11 @@ module ConstantPasswordConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof ConstantPasswordBarrier } + predicate isBarrierIn(DataFlow::Node node) { + // make sources barriers so that we only report the closest instance + isSource(node) + } + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(ConstantPasswordAdditionalFlowStep s).step(nodeFrom, nodeTo) } diff --git a/swift/ql/lib/codeql/swift/security/ConstantSaltQuery.qll b/swift/ql/lib/codeql/swift/security/ConstantSaltQuery.qll index 5d825642f30..e9b91d23570 100644 --- a/swift/ql/lib/codeql/swift/security/ConstantSaltQuery.qll +++ b/swift/ql/lib/codeql/swift/security/ConstantSaltQuery.qll @@ -31,6 +31,11 @@ module ConstantSaltConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof ConstantSaltBarrier } + predicate isBarrierIn(DataFlow::Node node) { + // make sources barriers so that we only report the closest instance + isSource(node) + } + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(ConstantSaltAdditionalFlowStep s).step(nodeFrom, nodeTo) } diff --git a/swift/ql/lib/codeql/swift/security/HardcodedEncryptionKeyQuery.qll b/swift/ql/lib/codeql/swift/security/HardcodedEncryptionKeyQuery.qll index 1e22072fe65..9e0cb16b7c6 100644 --- a/swift/ql/lib/codeql/swift/security/HardcodedEncryptionKeyQuery.qll +++ b/swift/ql/lib/codeql/swift/security/HardcodedEncryptionKeyQuery.qll @@ -38,14 +38,13 @@ module HardcodedKeyConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof HardcodedEncryptionKeyBarrier } - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - any(HardcodedEncryptionKeyAdditionalFlowStep s).step(nodeFrom, nodeTo) + predicate isBarrierIn(DataFlow::Node node) { + // make sources barriers so that we only report the closest instance + isSource(node) } - predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - // flow out of collections at the sink - isSink(node) and - c.getAReadContent() instanceof DataFlow::Content::CollectionContent + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + any(HardcodedEncryptionKeyAdditionalFlowStep s).step(nodeFrom, nodeTo) } } diff --git a/swift/ql/lib/codeql/swift/security/StaticInitializationVectorQuery.qll b/swift/ql/lib/codeql/swift/security/StaticInitializationVectorQuery.qll index d0276e978c1..5f281191d99 100644 --- a/swift/ql/lib/codeql/swift/security/StaticInitializationVectorQuery.qll +++ b/swift/ql/lib/codeql/swift/security/StaticInitializationVectorQuery.qll @@ -32,6 +32,11 @@ module StaticInitializationVectorConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof StaticInitializationVectorBarrier } + predicate isBarrierIn(DataFlow::Node node) { + // make sources barriers so that we only report the closest instance + isSource(node) + } + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(StaticInitializationVectorAdditionalFlowStep s).step(nodeFrom, nodeTo) } diff --git a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalQuery.qll b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalQuery.qll index af9305b3ef9..b79219ab633 100644 --- a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalQuery.qll +++ b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalQuery.qll @@ -22,16 +22,6 @@ module UnsafeJsEvalConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(UnsafeJsEvalAdditionalFlowStep s).step(nodeFrom, nodeTo) } - - predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - // flow out from content a the sink - ( - isSink(node) - or - isAdditionalFlowStep(node, _) - ) and - c.getAReadContent() instanceof DataFlow::Content::CollectionContent - } } /** diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 24082c2fa91..f1fbb9c70e0 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -2,15 +2,29 @@ edges | conversions.swift:33:16:33:26 | call to sourceInt() | conversions.swift:33:12:33:27 | call to Self.init(_:) | | conversions.swift:34:18:34:28 | call to sourceInt() | conversions.swift:34:12:34:29 | call to Self.init(_:) | | conversions.swift:35:18:35:28 | call to sourceInt() | conversions.swift:35:12:35:29 | call to Float.init(_:) | +| conversions.swift:36:12:36:30 | call to String.init(_:) [Collection element] | conversions.swift:36:12:36:30 | call to String.init(_:) | | conversions.swift:36:19:36:29 | call to sourceInt() | conversions.swift:36:12:36:30 | call to String.init(_:) | +| conversions.swift:36:19:36:29 | call to sourceInt() | conversions.swift:36:12:36:30 | call to String.init(_:) [Collection element] | | conversions.swift:37:12:37:30 | call to String.init(_:) | conversions.swift:37:12:37:32 | .utf8 | | conversions.swift:37:19:37:29 | call to sourceInt() | conversions.swift:37:12:37:30 | call to String.init(_:) | +| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:40:12:40:12 | arr | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:41:12:41:12 | arr [Collection element] | +| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:41:12:41:17 | ...[...] | +| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:42:20:42:20 | arr | +| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:42:20:42:20 | arr [Collection element] | +| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:43:20:43:20 | arr | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:43:20:43:20 | arr [Collection element] | | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:39:12:39:30 | [...] [Collection element] | | conversions.swift:41:12:41:12 | arr [Collection element] | conversions.swift:41:12:41:17 | ...[...] | +| conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | conversions.swift:42:12:42:23 | call to Array.init(_:) | +| conversions.swift:42:20:42:20 | arr | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | +| conversions.swift:42:20:42:20 | arr [Collection element] | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | conversions.swift:43:12:43:26 | ...[...] | +| conversions.swift:43:20:43:20 | arr | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | | conversions.swift:43:20:43:20 | arr [Collection element] | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | +| conversions.swift:44:12:44:39 | call to Array.init(_:) [Collection element] | conversions.swift:44:12:44:39 | call to Array.init(_:) | +| conversions.swift:44:20:44:33 | call to sourceString() | conversions.swift:44:20:44:35 | .utf8 | +| conversions.swift:44:20:44:35 | .utf8 | conversions.swift:44:12:44:39 | call to Array.init(_:) [Collection element] | | conversions.swift:45:12:45:39 | call to Array.init(_:) [Collection element] | conversions.swift:45:12:45:42 | ...[...] | | conversions.swift:45:20:45:33 | call to sourceString() | conversions.swift:45:20:45:35 | .utf8 | | conversions.swift:45:20:45:35 | .utf8 | conversions.swift:45:12:45:39 | call to Array.init(_:) [Collection element] | @@ -40,13 +54,19 @@ edges | conversions.swift:80:12:80:22 | call to sourceInt() | conversions.swift:80:12:80:24 | .bigEndian | | conversions.swift:109:18:109:30 | call to sourceFloat() | conversions.swift:109:12:109:31 | call to Float.init(_:) | | conversions.swift:110:18:110:30 | call to sourceFloat() | conversions.swift:110:12:110:31 | call to UInt8.init(_:) | +| conversions.swift:111:12:111:32 | call to String.init(_:) [Collection element] | conversions.swift:111:12:111:32 | call to String.init(_:) | | conversions.swift:111:19:111:31 | call to sourceFloat() | conversions.swift:111:12:111:32 | call to String.init(_:) | +| conversions.swift:111:19:111:31 | call to sourceFloat() | conversions.swift:111:12:111:32 | call to String.init(_:) [Collection element] | | conversions.swift:112:12:112:32 | call to String.init(_:) | conversions.swift:112:12:112:34 | .utf8 | | conversions.swift:112:19:112:31 | call to sourceFloat() | conversions.swift:112:12:112:32 | call to String.init(_:) | +| conversions.swift:113:12:113:34 | call to String.init(_:) [Collection element] | conversions.swift:113:12:113:34 | call to String.init(_:) | | conversions.swift:113:19:113:33 | call to sourceFloat80() | conversions.swift:113:12:113:34 | call to String.init(_:) | +| conversions.swift:113:19:113:33 | call to sourceFloat80() | conversions.swift:113:12:113:34 | call to String.init(_:) [Collection element] | | conversions.swift:114:12:114:34 | call to String.init(_:) | conversions.swift:114:12:114:36 | .utf8 | | conversions.swift:114:19:114:33 | call to sourceFloat80() | conversions.swift:114:12:114:34 | call to String.init(_:) | +| conversions.swift:115:12:115:33 | call to String.init(_:) [Collection element] | conversions.swift:115:12:115:33 | call to String.init(_:) | | conversions.swift:115:19:115:32 | call to sourceDouble() | conversions.swift:115:12:115:33 | call to String.init(_:) | +| conversions.swift:115:19:115:32 | call to sourceDouble() | conversions.swift:115:12:115:33 | call to String.init(_:) [Collection element] | | conversions.swift:116:12:116:33 | call to String.init(_:) | conversions.swift:116:12:116:35 | .utf8 | | conversions.swift:116:19:116:32 | call to sourceDouble() | conversions.swift:116:12:116:33 | call to String.init(_:) | | conversions.swift:118:18:118:30 | call to sourceFloat() | conversions.swift:118:12:118:31 | call to Float.init(_:) | @@ -61,7 +81,9 @@ edges | conversions.swift:129:12:129:25 | call to sourceDouble() | conversions.swift:129:12:129:27 | .significand | | conversions.swift:130:12:130:23 | call to sourceUInt() | conversions.swift:130:12:130:25 | .byteSwapped | | conversions.swift:131:12:131:25 | call to sourceUInt64() | conversions.swift:131:12:131:27 | .byteSwapped | +| conversions.swift:136:12:136:33 | call to String.init(_:) [Collection element] | conversions.swift:136:12:136:33 | call to String.init(_:) | | conversions.swift:136:19:136:32 | call to sourceString() | conversions.swift:136:12:136:33 | call to String.init(_:) | +| conversions.swift:136:19:136:32 | call to sourceString() | conversions.swift:136:12:136:33 | call to String.init(_:) [Collection element] | | conversions.swift:144:12:144:35 | call to MyString.init(_:) | conversions.swift:144:12:144:35 | call to MyString.init(_:) [some:0] | | conversions.swift:144:12:144:35 | call to MyString.init(_:) | conversions.swift:145:12:145:12 | ms2 | | conversions.swift:144:12:144:35 | call to MyString.init(_:) | conversions.swift:146:12:146:16 | .description | @@ -82,20 +104,34 @@ edges | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:175:13:175:19 | ...[...] | | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:178:25:178:25 | arr1 | | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:185:31:185:31 | arr1 | +| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:174:13:174:13 | arr2 | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:13 | arr2 [Collection element] | +| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:19 | ...[...] | +| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:179:25:179:25 | arr2 | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:179:25:179:25 | arr2 [Collection element] | +| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:186:31:186:31 | arr2 | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:186:31:186:31 | arr2 [Collection element] | | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:172:14:172:26 | [...] [Collection element] | | conversions.swift:176:13:176:13 | arr2 [Collection element] | conversions.swift:176:13:176:19 | ...[...] | +| conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:180:13:180:13 | arr1b | | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:182:13:182:13 | arr1b [Collection element] | +| conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:182:13:182:20 | ...[...] | | conversions.swift:178:25:178:25 | arr1 | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | +| conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:181:13:181:13 | arr2b | | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:183:13:183:13 | arr2b [Collection element] | +| conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:183:13:183:20 | ...[...] | +| conversions.swift:179:25:179:25 | arr2 | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | | conversions.swift:179:25:179:25 | arr2 [Collection element] | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | | conversions.swift:182:13:182:13 | arr1b [Collection element] | conversions.swift:182:13:182:20 | ...[...] | | conversions.swift:183:13:183:13 | arr2b [Collection element] | conversions.swift:183:13:183:20 | ...[...] | +| conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:187:13:187:13 | arr1c | | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:189:13:189:13 | arr1c [Collection element] | +| conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:189:13:189:20 | ...[...] | | conversions.swift:185:31:185:31 | arr1 | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | +| conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:188:13:188:13 | arr2c | | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:190:13:190:13 | arr2c [Collection element] | +| conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:190:13:190:20 | ...[...] | +| conversions.swift:186:31:186:31 | arr2 | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | | conversions.swift:186:31:186:31 | arr2 [Collection element] | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | | conversions.swift:189:13:189:13 | arr1c [Collection element] | conversions.swift:189:13:189:20 | ...[...] | | conversions.swift:190:13:190:13 | arr2c [Collection element] | conversions.swift:190:13:190:20 | ...[...] | @@ -188,17 +224,28 @@ nodes | conversions.swift:35:12:35:29 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | | conversions.swift:35:18:35:28 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:36:12:36:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:36:12:36:30 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:36:19:36:29 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:37:12:37:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:37:12:37:32 | .utf8 | semmle.label | .utf8 | | conversions.swift:37:19:37:29 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:39:12:39:30 | [...] [Collection element] | semmle.label | [...] [Collection element] | | conversions.swift:39:19:39:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:40:12:40:12 | arr | semmle.label | arr | | conversions.swift:41:12:41:12 | arr [Collection element] | semmle.label | arr [Collection element] | | conversions.swift:41:12:41:17 | ...[...] | semmle.label | ...[...] | +| conversions.swift:42:12:42:23 | call to Array.init(_:) | semmle.label | call to Array.init(_:) | +| conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| conversions.swift:42:20:42:20 | arr | semmle.label | arr | +| conversions.swift:42:20:42:20 | arr [Collection element] | semmle.label | arr [Collection element] | | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:43:12:43:26 | ...[...] | semmle.label | ...[...] | +| conversions.swift:43:20:43:20 | arr | semmle.label | arr | | conversions.swift:43:20:43:20 | arr [Collection element] | semmle.label | arr [Collection element] | +| conversions.swift:44:12:44:39 | call to Array.init(_:) | semmle.label | call to Array.init(_:) | +| conversions.swift:44:12:44:39 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| conversions.swift:44:20:44:33 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:44:20:44:35 | .utf8 | semmle.label | .utf8 | | conversions.swift:45:12:45:39 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:45:12:45:42 | ...[...] | semmle.label | ...[...] | | conversions.swift:45:20:45:33 | call to sourceString() | semmle.label | call to sourceString() | @@ -249,16 +296,19 @@ nodes | conversions.swift:110:12:110:31 | call to UInt8.init(_:) | semmle.label | call to UInt8.init(_:) | | conversions.swift:110:18:110:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | | conversions.swift:111:12:111:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:111:12:111:32 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:111:19:111:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | | conversions.swift:112:12:112:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:112:12:112:34 | .utf8 | semmle.label | .utf8 | | conversions.swift:112:19:112:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | | conversions.swift:113:12:113:34 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:113:12:113:34 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:113:19:113:33 | call to sourceFloat80() | semmle.label | call to sourceFloat80() | | conversions.swift:114:12:114:34 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:114:12:114:36 | .utf8 | semmle.label | .utf8 | | conversions.swift:114:19:114:33 | call to sourceFloat80() | semmle.label | call to sourceFloat80() | | conversions.swift:115:12:115:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:115:12:115:33 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:115:19:115:32 | call to sourceDouble() | semmle.label | call to sourceDouble() | | conversions.swift:116:12:116:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:116:12:116:35 | .utf8 | semmle.label | .utf8 | @@ -289,6 +339,7 @@ nodes | conversions.swift:131:12:131:27 | .byteSwapped | semmle.label | .byteSwapped | | conversions.swift:135:12:135:25 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:136:12:136:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:136:12:136:33 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:136:19:136:32 | call to sourceString() | semmle.label | call to sourceString() | | conversions.swift:144:12:144:35 | call to MyString.init(_:) | semmle.label | call to MyString.init(_:) | | conversions.swift:144:12:144:35 | call to MyString.init(_:) [some:0] | semmle.label | call to MyString.init(_:) [some:0] | @@ -310,13 +361,17 @@ nodes | conversions.swift:172:14:172:26 | [...] [Collection element] | semmle.label | [...] [Collection element] | | conversions.swift:172:15:172:25 | call to sourceInt() | semmle.label | call to sourceInt() | | conversions.swift:173:13:173:13 | arr1 | semmle.label | arr1 | +| conversions.swift:174:13:174:13 | arr2 | semmle.label | arr2 | | conversions.swift:175:13:175:19 | ...[...] | semmle.label | ...[...] | | conversions.swift:176:13:176:13 | arr2 [Collection element] | semmle.label | arr2 [Collection element] | | conversions.swift:176:13:176:19 | ...[...] | semmle.label | ...[...] | | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:178:25:178:25 | arr1 | semmle.label | arr1 | | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| conversions.swift:179:25:179:25 | arr2 | semmle.label | arr2 | | conversions.swift:179:25:179:25 | arr2 [Collection element] | semmle.label | arr2 [Collection element] | +| conversions.swift:180:13:180:13 | arr1b | semmle.label | arr1b | +| conversions.swift:181:13:181:13 | arr2b | semmle.label | arr2b | | conversions.swift:182:13:182:13 | arr1b [Collection element] | semmle.label | arr1b [Collection element] | | conversions.swift:182:13:182:20 | ...[...] | semmle.label | ...[...] | | conversions.swift:183:13:183:13 | arr2b [Collection element] | semmle.label | arr2b [Collection element] | @@ -324,7 +379,10 @@ nodes | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | semmle.label | call to ContiguousArray.init(_:) [Collection element] | | conversions.swift:185:31:185:31 | arr1 | semmle.label | arr1 | | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | semmle.label | call to ContiguousArray.init(_:) [Collection element] | +| conversions.swift:186:31:186:31 | arr2 | semmle.label | arr2 | | conversions.swift:186:31:186:31 | arr2 [Collection element] | semmle.label | arr2 [Collection element] | +| conversions.swift:187:13:187:13 | arr1c | semmle.label | arr1c | +| conversions.swift:188:13:188:13 | arr2c | semmle.label | arr2c | | conversions.swift:189:13:189:13 | arr1c [Collection element] | semmle.label | arr1c [Collection element] | | conversions.swift:189:13:189:20 | ...[...] | semmle.label | ...[...] | | conversions.swift:190:13:190:13 | arr2c [Collection element] | semmle.label | arr2c [Collection element] | @@ -462,8 +520,11 @@ subpaths | conversions.swift:35:12:35:29 | call to Float.init(_:) | conversions.swift:35:18:35:28 | call to sourceInt() | conversions.swift:35:12:35:29 | call to Float.init(_:) | result | | conversions.swift:36:12:36:30 | call to String.init(_:) | conversions.swift:36:19:36:29 | call to sourceInt() | conversions.swift:36:12:36:30 | call to String.init(_:) | result | | conversions.swift:37:12:37:32 | .utf8 | conversions.swift:37:19:37:29 | call to sourceInt() | conversions.swift:37:12:37:32 | .utf8 | result | +| conversions.swift:40:12:40:12 | arr | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:40:12:40:12 | arr | result | | conversions.swift:41:12:41:17 | ...[...] | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:41:12:41:17 | ...[...] | result | +| conversions.swift:42:12:42:23 | call to Array.init(_:) | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:42:12:42:23 | call to Array.init(_:) | result | | conversions.swift:43:12:43:26 | ...[...] | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:43:12:43:26 | ...[...] | result | +| conversions.swift:44:12:44:39 | call to Array.init(_:) | conversions.swift:44:20:44:33 | call to sourceString() | conversions.swift:44:12:44:39 | call to Array.init(_:) | result | | conversions.swift:45:12:45:42 | ...[...] | conversions.swift:45:20:45:33 | call to sourceString() | conversions.swift:45:12:45:42 | ...[...] | result | | conversions.swift:48:13:48:13 | v | conversions.swift:47:13:47:23 | call to sourceInt() | conversions.swift:48:13:48:13 | v | result | | conversions.swift:52:12:52:12 | v2 | conversions.swift:51:30:51:40 | call to sourceInt() | conversions.swift:52:12:52:12 | v2 | result | @@ -513,10 +574,15 @@ subpaths | conversions.swift:158:12:158:12 | v3 | conversions.swift:152:31:152:44 | call to sourceString() | conversions.swift:158:12:158:12 | v3 | result | | conversions.swift:166:12:166:35 | call to Self.init(_:) | conversions.swift:166:24:166:34 | call to sourceInt() | conversions.swift:166:12:166:35 | call to Self.init(_:) | result | | conversions.swift:173:13:173:13 | arr1 | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:173:13:173:13 | arr1 | result | +| conversions.swift:174:13:174:13 | arr2 | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:174:13:174:13 | arr2 | result | | conversions.swift:175:13:175:19 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:175:13:175:19 | ...[...] | result | | conversions.swift:176:13:176:19 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:176:13:176:19 | ...[...] | result | +| conversions.swift:180:13:180:13 | arr1b | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:180:13:180:13 | arr1b | result | +| conversions.swift:181:13:181:13 | arr2b | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:181:13:181:13 | arr2b | result | | conversions.swift:182:13:182:20 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:182:13:182:20 | ...[...] | result | | conversions.swift:183:13:183:20 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:183:13:183:20 | ...[...] | result | +| conversions.swift:187:13:187:13 | arr1c | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:187:13:187:13 | arr1c | result | +| conversions.swift:188:13:188:13 | arr2c | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:188:13:188:13 | arr2c | result | | conversions.swift:189:13:189:20 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:189:13:189:20 | ...[...] | result | | conversions.swift:190:13:190:20 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:190:13:190:20 | ...[...] | result | | simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift index 3618dd18de5..f7cf9faf1a9 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -37,11 +37,11 @@ func testConversions() { sink(arg: String(sourceInt()).utf8) // $ tainted=37 let arr = [1, 2, sourceInt()] - sink(arg: arr) + sink(arg: arr) // $ tainted=39 sink(arg: arr[0]) // $ tainted=39 - sink(arg: [MyInt](arr)) + sink(arg: [MyInt](arr)) // $ tainted=39 sink(arg: [MyInt](arr)[0]) // $ tainted=39 - sink(arg: [UInt8](sourceString().utf8)) + sink(arg: [UInt8](sourceString().utf8)) // $ tainted=44 sink(arg: [UInt8](sourceString().utf8)[0]) // $ tainted=45 if let v = sourceInt() as? UInt { @@ -171,21 +171,21 @@ class TestArrayConversion { let arr1 = sourceArray() let arr2 = [sourceInt()] sink(arg: arr1) // $ tainted=171 - sink(arg: arr2) + sink(arg: arr2) // $ tainted=172 sink(arg: arr1[0]) // $ tainted=171 sink(arg: arr2[0]) // $ tainted=172 let arr1b = try Array(arr1) let arr2b = try Array(arr2) - sink(arg: arr1b) - sink(arg: arr2b) + sink(arg: arr1b) // $ tainted=171 + sink(arg: arr2b) // $ tainted=172 sink(arg: arr1b[0]) // $ tainted=171 sink(arg: arr2b[0]) // $ tainted=172 let arr1c = ContiguousArray(arr1) let arr2c = ContiguousArray(arr2) - sink(arg: arr1c) - sink(arg: arr2c) + sink(arg: arr1c) // $ tainted=171 + sink(arg: arr2c) // $ tainted=172 sink(arg: arr1c[0]) // $ tainted=171 sink(arg: arr2c[0]) // $ tainted=172 } diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/int.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/int.swift index c4cd65dade5..45b6f751587 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/int.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/int.swift @@ -11,11 +11,11 @@ func taintThroughClosurePointer() { var myArray1: [UInt8] = [1, 2, 3, 4] myArray1[0] = source() - sink(arg: myArray1) + sink(arg: myArray1) // $ tainted=13 sink(arg: myArray1[0]) // $ tainted=13 let return1 = myArray1.withUnsafeBytes({ ptr1 in - sink(arg: ptr1) + sink(arg: ptr1) // $ tainted=13 sink(arg: ptr1[0]) // $ tainted=13 return source() }) @@ -26,11 +26,11 @@ func taintThroughClosurePointer() { var myArray2: [UInt8] = [1, 2, 3, 4] myArray2[0] = source() - sink(arg: myArray2) + sink(arg: myArray2) // $ tainted=28 sink(arg: myArray2[0]) // $ tainted=28 let return2 = myArray2.withUnsafeBufferPointer({ ptr2 in - sink(arg: ptr2) + sink(arg: ptr2) // $ tainted=28 sink(arg: ptr2[0]) // $ tainted=28 return source() }) @@ -45,13 +45,13 @@ func taintThroughMutablePointer() { let return1 = myArray1.withUnsafeMutableBufferPointer({ buffer in buffer.update(repeating: source()) - sink(arg: buffer) + sink(arg: buffer) // $ tainted=47 sink(arg: buffer[0]) // $ tainted=47 sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=47 return source() }) sink(arg: return1) // $ tainted=51 - sink(arg: myArray1) + sink(arg: myArray1) // $ tainted=47 sink(arg: myArray1[0]) // $ tainted=47 // --- @@ -81,12 +81,12 @@ func taintThroughMutablePointer() { let return3 = myArray3.withContiguousMutableStorageIfAvailable({ ptr in ptr.update(repeating: source()) - sink(arg: ptr) + sink(arg: ptr) // $ tainted=83 sink(arg: ptr[0]) // $ tainted=83 return source() }) sink(arg: return3!) // $ tainted=86 - sink(arg: myArray3) + sink(arg: myArray3) // $ tainted=83 sink(arg: myArray3[0]) // $ tainted=83 // --- @@ -97,7 +97,7 @@ func taintThroughMutablePointer() { myArray5[0] = source() sink(arg: myArray4) sink(arg: myArray4[0]) - sink(arg: myArray5) + sink(arg: myArray5) // $ tainted=97 sink(arg: myArray5[0]) // $ tainted=97 let return4 = myArray4.withUnsafeMutableBytes({ ptr4 in @@ -116,7 +116,7 @@ func taintThroughMutablePointer() { sink(arg: return4) // $ tainted=114 sink(arg: myArray4) sink(arg: myArray4[0]) // $ MISSING: tainted=97 - sink(arg: myArray5) + sink(arg: myArray5) // $ tainted=97 sink(arg: myArray5[0]) // $ tainted=97 // --- @@ -129,22 +129,22 @@ func taintThroughMutablePointer() { let return6 = myMutableBuffer.withContiguousMutableStorageIfAvailable({ ptr in ptr.update(repeating: source2()) - sink(arg: ptr) + sink(arg: ptr) // $ tainted=131 sink(arg: ptr[0]) // $ tainted=131 return source() }) sink(arg: return6!) // $ tainted=134 - sink(arg: myMutableBuffer) + sink(arg: myMutableBuffer) // $ tainted=131 sink(arg: myMutableBuffer[0]) // $ tainted=131 } func taintCollections(array: inout Array, contiguousArray: inout ContiguousArray, dictionary: inout Dictionary) { array[0] = source2() - sink(arg: array) + sink(arg: array) // $ tainted=142 sink(arg: array[0]) // $ tainted=142 array.withContiguousStorageIfAvailable({ buffer in - sink(arg: buffer) + sink(arg: buffer) // $ tainted=142 sink(arg: buffer[0]) // $ tainted=142 sink(arg: array) sink(arg: array[0]) // $ MISSING: tainted=142 diff --git a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected index 848ce4937ae..74adec1c605 100644 --- a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected +++ b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected @@ -12,7 +12,11 @@ edges | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | rncryptor.swift:83:113:83:113 | myConstIV4 | | rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | | test.swift:53:19:53:34 | iv | test.swift:54:17:54:17 | iv | +| test.swift:85:3:85:3 | this string is constant | test.swift:89:10:89:28 | call to getConstantString() | | test.swift:85:3:85:3 | this string is constant | test.swift:101:17:101:35 | call to getConstantString() | +| test.swift:89:2:89:34 | call to Array.init(_:) [Collection element] | test.swift:100:12:100:29 | call to getConstantArray() [Collection element] | +| test.swift:89:10:89:28 | call to getConstantString() | test.swift:89:10:89:30 | .utf8 | +| test.swift:89:10:89:30 | .utf8 | test.swift:89:2:89:34 | call to Array.init(_:) [Collection element] | | test.swift:99:25:99:120 | [...] | test.swift:128:33:128:33 | iv | | test.swift:99:25:99:120 | [...] | test.swift:135:22:135:22 | iv | | test.swift:99:25:99:120 | [...] | test.swift:139:22:139:22 | iv | @@ -27,6 +31,7 @@ edges | test.swift:99:25:99:120 | [...] | test.swift:162:22:162:22 | iv | | test.swift:99:25:99:120 | [...] | test.swift:167:22:167:22 | iv | | test.swift:99:25:99:120 | [...] | test.swift:168:22:168:22 | iv | +| test.swift:100:12:100:29 | call to getConstantArray() [Collection element] | test.swift:129:33:129:33 | iv2 | | test.swift:101:17:101:35 | call to getConstantString() | test.swift:112:36:112:36 | ivString | | test.swift:101:17:101:35 | call to getConstantString() | test.swift:113:36:113:36 | ivString | | test.swift:101:17:101:35 | call to getConstantString() | test.swift:118:41:118:41 | ivString | @@ -54,7 +59,11 @@ nodes | test.swift:53:19:53:34 | iv | semmle.label | iv | | test.swift:54:17:54:17 | iv | semmle.label | iv | | test.swift:85:3:85:3 | this string is constant | semmle.label | this string is constant | +| test.swift:89:2:89:34 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| test.swift:89:10:89:28 | call to getConstantString() | semmle.label | call to getConstantString() | +| test.swift:89:10:89:30 | .utf8 | semmle.label | .utf8 | | test.swift:99:25:99:120 | [...] | semmle.label | [...] | +| test.swift:100:12:100:29 | call to getConstantArray() [Collection element] | semmle.label | call to getConstantArray() [Collection element] | | test.swift:101:17:101:35 | call to getConstantString() | semmle.label | call to getConstantString() | | test.swift:112:36:112:36 | ivString | semmle.label | ivString | | test.swift:113:36:113:36 | ivString | semmle.label | ivString | @@ -62,6 +71,7 @@ nodes | test.swift:122:41:122:41 | ivString | semmle.label | ivString | | test.swift:123:41:123:41 | ivString | semmle.label | ivString | | test.swift:128:33:128:33 | iv | semmle.label | iv | +| test.swift:129:33:129:33 | iv2 | semmle.label | iv2 | | test.swift:130:39:130:39 | ivString | semmle.label | ivString | | test.swift:135:22:135:22 | iv | semmle.label | iv | | test.swift:139:22:139:22 | iv | semmle.label | iv | @@ -93,6 +103,7 @@ subpaths | test.swift:122:41:122:41 | ivString | test.swift:85:3:85:3 | this string is constant | test.swift:122:41:122:41 | ivString | The static value 'this string is constant' is used as an initialization vector for encryption. | | test.swift:123:41:123:41 | ivString | test.swift:85:3:85:3 | this string is constant | test.swift:123:41:123:41 | ivString | The static value 'this string is constant' is used as an initialization vector for encryption. | | test.swift:128:33:128:33 | iv | test.swift:99:25:99:120 | [...] | test.swift:128:33:128:33 | iv | The static value '[...]' is used as an initialization vector for encryption. | +| test.swift:129:33:129:33 | iv2 | test.swift:85:3:85:3 | this string is constant | test.swift:129:33:129:33 | iv2 | The static value 'this string is constant' is used as an initialization vector for encryption. | | test.swift:130:39:130:39 | ivString | test.swift:85:3:85:3 | this string is constant | test.swift:130:39:130:39 | ivString | The static value 'this string is constant' is used as an initialization vector for encryption. | | test.swift:135:22:135:22 | iv | test.swift:99:25:99:120 | [...] | test.swift:135:22:135:22 | iv | The static value '[...]' is used as an initialization vector for encryption. | | test.swift:139:22:139:22 | iv | test.swift:99:25:99:120 | [...] | test.swift:139:22:139:22 | iv | The static value '[...]' is used as an initialization vector for encryption. | diff --git a/swift/ql/test/query-tests/Security/CWE-1204/test.swift b/swift/ql/test/query-tests/Security/CWE-1204/test.swift index 441393e1314..273556ce5bb 100644 --- a/swift/ql/test/query-tests/Security/CWE-1204/test.swift +++ b/swift/ql/test/query-tests/Security/CWE-1204/test.swift @@ -34,7 +34,7 @@ class Rabbit protocol BlockMode { } -struct CBC: BlockMode { +struct CBC: BlockMode { init(iv: Array) { } } @@ -50,7 +50,7 @@ struct CFB: BlockMode { final class GCM: BlockMode { enum Mode { case combined, detached } init(iv: Array, additionalAuthenticatedData: Array? = nil, tagLength: Int = 16, mode: Mode = .detached) { } - convenience init(iv: Array, authenticationTag: Array, additionalAuthenticatedData: Array? = nil, mode: Mode = .detached) { + convenience init(iv: Array, authenticationTag: Array, additionalAuthenticatedData: Array? = nil, mode: Mode = .detached) { self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) } } @@ -126,7 +126,7 @@ func test() { // Rabbit let rb1 = Rabbit(key: key, iv: iv) // BAD - let rb2 = Rabbit(key: key, iv: iv2) // BAD [NOT DETECTED] + let rb2 = Rabbit(key: key, iv: iv2) // BAD let rb3 = Rabbit(key: keyString, iv: ivString) // BAD let rg1 = Rabbit(key: key, iv: randomIv) // GOOD let rg2 = Rabbit(key: keyString, iv: randomIvString) // GOOD diff --git a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected index a3f4c333024..11c1950f3a9 100644 --- a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected +++ b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected @@ -17,10 +17,18 @@ edges | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:105:32:105:32 | myConstPassword | | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:107:61:107:61 | myConstPassword | | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:108:97:108:97 | myConstPassword | +| test.swift:29:3:29:3 | this string is constant | test.swift:33:10:33:28 | call to getConstantString() | +| test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | +| test.swift:33:10:33:28 | call to getConstantString() | test.swift:33:10:33:30 | .utf8 | +| test.swift:33:10:33:30 | .utf8 | test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | | test.swift:43:39:43:134 | [...] | test.swift:51:30:51:30 | constantPassword | | test.swift:43:39:43:134 | [...] | test.swift:56:40:56:40 | constantPassword | | test.swift:43:39:43:134 | [...] | test.swift:62:40:62:40 | constantPassword | | test.swift:43:39:43:134 | [...] | test.swift:67:34:67:34 | constantPassword | +| test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | test.swift:52:30:52:30 | constantStringPassword | +| test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | test.swift:57:40:57:40 | constantStringPassword | +| test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | test.swift:63:40:63:40 | constantStringPassword | +| test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | test.swift:68:34:68:34 | constantStringPassword | nodes | rncryptor.swift:69:24:69:24 | abc123 | semmle.label | abc123 | | rncryptor.swift:77:89:77:89 | myConstPassword | semmle.label | myConstPassword | @@ -41,11 +49,20 @@ nodes | rncryptor.swift:105:32:105:32 | myConstPassword | semmle.label | myConstPassword | | rncryptor.swift:107:61:107:61 | myConstPassword | semmle.label | myConstPassword | | rncryptor.swift:108:97:108:97 | myConstPassword | semmle.label | myConstPassword | +| test.swift:29:3:29:3 | this string is constant | semmle.label | this string is constant | +| test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| test.swift:33:10:33:28 | call to getConstantString() | semmle.label | call to getConstantString() | +| test.swift:33:10:33:30 | .utf8 | semmle.label | .utf8 | | test.swift:43:39:43:134 | [...] | semmle.label | [...] | +| test.swift:44:31:44:48 | call to getConstantArray() [Collection element] | semmle.label | call to getConstantArray() [Collection element] | | test.swift:51:30:51:30 | constantPassword | semmle.label | constantPassword | +| test.swift:52:30:52:30 | constantStringPassword | semmle.label | constantStringPassword | | test.swift:56:40:56:40 | constantPassword | semmle.label | constantPassword | +| test.swift:57:40:57:40 | constantStringPassword | semmle.label | constantStringPassword | | test.swift:62:40:62:40 | constantPassword | semmle.label | constantPassword | +| test.swift:63:40:63:40 | constantStringPassword | semmle.label | constantStringPassword | | test.swift:67:34:67:34 | constantPassword | semmle.label | constantPassword | +| test.swift:68:34:68:34 | constantStringPassword | semmle.label | constantStringPassword | subpaths #select | rncryptor.swift:77:89:77:89 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:77:89:77:89 | myConstPassword | The value 'abc123' is used as a constant password. | @@ -67,6 +84,10 @@ subpaths | rncryptor.swift:107:61:107:61 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:107:61:107:61 | myConstPassword | The value 'abc123' is used as a constant password. | | rncryptor.swift:108:97:108:97 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 | rncryptor.swift:108:97:108:97 | myConstPassword | The value 'abc123' is used as a constant password. | | test.swift:51:30:51:30 | constantPassword | test.swift:43:39:43:134 | [...] | test.swift:51:30:51:30 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:52:30:52:30 | constantStringPassword | test.swift:29:3:29:3 | this string is constant | test.swift:52:30:52:30 | constantStringPassword | The value 'this string is constant' is used as a constant password. | | test.swift:56:40:56:40 | constantPassword | test.swift:43:39:43:134 | [...] | test.swift:56:40:56:40 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:57:40:57:40 | constantStringPassword | test.swift:29:3:29:3 | this string is constant | test.swift:57:40:57:40 | constantStringPassword | The value 'this string is constant' is used as a constant password. | | test.swift:62:40:62:40 | constantPassword | test.swift:43:39:43:134 | [...] | test.swift:62:40:62:40 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:63:40:63:40 | constantStringPassword | test.swift:29:3:29:3 | this string is constant | test.swift:63:40:63:40 | constantStringPassword | The value 'this string is constant' is used as a constant password. | | test.swift:67:34:67:34 | constantPassword | test.swift:43:39:43:134 | [...] | test.swift:67:34:67:34 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:68:34:68:34 | constantStringPassword | test.swift:29:3:29:3 | this string is constant | test.swift:68:34:68:34 | constantStringPassword | The value 'this string is constant' is used as a constant password. | diff --git a/swift/ql/test/query-tests/Security/CWE-259/test.swift b/swift/ql/test/query-tests/Security/CWE-259/test.swift index ec28b8f5013..923c49bffbd 100644 --- a/swift/ql/test/query-tests/Security/CWE-259/test.swift +++ b/swift/ql/test/query-tests/Security/CWE-259/test.swift @@ -46,25 +46,25 @@ func test() { let randomArray = getRandomArray() let variant = Variant.sha2 let iterations = 120120 - + // HKDF test cases let hkdfb1 = HKDF(password: constantPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD - let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD [NOT DETECTED] + let hkdfb2 = HKDF(password: constantStringPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // BAD let hkdfg1 = HKDF(password: randomPassword, salt: randomArray, info: randomArray, keyLength: 0, variant: variant) // GOOD // PBKDF1 test cases let pbkdf1b1 = PKCS5.PBKDF1(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD - let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD [NOT DETECTED] + let pbkdf1b2 = PKCS5.PBKDF1(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD let pbkdf1g1 = PKCS5.PBKDF1(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD // PBKDF2 test cases let pbkdf2b1 = PKCS5.PBKDF2(password: constantPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD - let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD [NOT DETECTED] + let pbkdf2b2 = PKCS5.PBKDF2(password: constantStringPassword, salt: randomArray, iterations: iterations, keyLength: 0) // BAD let pbkdf2g1 = PKCS5.PBKDF2(password: randomPassword, salt: randomArray, iterations: iterations, keyLength: 0) // GOOD // Scrypt test cases let scryptb1 = Scrypt(password: constantPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD - let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD [NOT DETECTED] + let scryptb2 = Scrypt(password: constantStringPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // BAD let scryptg1 = Scrypt(password: randomPassword, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD -} \ No newline at end of file +} diff --git a/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift b/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift index edc92821bd2..46d3981e19a 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift +++ b/swift/ql/test/query-tests/Security/CWE-321/cryptoswift.swift @@ -61,7 +61,7 @@ enum Variant { protocol BlockMode { } -struct CBC: BlockMode { +struct CBC: BlockMode { init() { } } @@ -98,13 +98,13 @@ func test() { let blockMode = CBC() let padding = Padding.noPadding let variant = Variant.sha2 - + let iv = getRandomArray() let ivString = String(cString: iv) // AES test cases - let ab1 = AES(key: key2, blockMode: blockMode, padding: padding) // BAD [NOT DETECTED] - let ab2 = AES(key: key2, blockMode: blockMode) // BAD [NOT DETECTED] + let ab1 = AES(key: key2, blockMode: blockMode, padding: padding) // BAD + let ab2 = AES(key: key2, blockMode: blockMode) // BAD let ab3 = AES(key: keyString, iv: ivString) // BAD let ab4 = AES(key: keyString, iv: ivString, padding: padding) // BAD diff --git a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected index cd9fda87e19..033d4481780 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected +++ b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected @@ -11,10 +11,18 @@ edges | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:76:152:76:152 | myConstantSalt2 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:79:160:79:160 | myConstantSalt2 | | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | +| test.swift:29:3:29:3 | this string is constant | test.swift:33:10:33:28 | call to getConstantString() | +| test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | +| test.swift:33:10:33:28 | call to getConstantString() | test.swift:33:10:33:30 | .utf8 | +| test.swift:33:10:33:30 | .utf8 | test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | | test.swift:43:35:43:130 | [...] | test.swift:51:49:51:49 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:56:59:56:59 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:62:59:62:59 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:67:53:67:53 | constantSalt | +| test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | test.swift:52:49:52:49 | constantStringSalt | +| test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | test.swift:57:59:57:59 | constantStringSalt | +| test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | test.swift:63:59:63:59 | constantStringSalt | +| test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | test.swift:68:53:68:53 | constantStringSalt | nodes | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:59:29:59:29 | abcdef123456 | semmle.label | abcdef123456 | @@ -30,11 +38,20 @@ nodes | rncryptor.swift:76:152:76:152 | myConstantSalt2 | semmle.label | myConstantSalt2 | | rncryptor.swift:78:135:78:135 | myConstantSalt1 | semmle.label | myConstantSalt1 | | rncryptor.swift:79:160:79:160 | myConstantSalt2 | semmle.label | myConstantSalt2 | +| test.swift:29:3:29:3 | this string is constant | semmle.label | this string is constant | +| test.swift:33:2:33:34 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| test.swift:33:10:33:28 | call to getConstantString() | semmle.label | call to getConstantString() | +| test.swift:33:10:33:30 | .utf8 | semmle.label | .utf8 | | test.swift:43:35:43:130 | [...] | semmle.label | [...] | +| test.swift:44:27:44:44 | call to getConstantArray() [Collection element] | semmle.label | call to getConstantArray() [Collection element] | | test.swift:51:49:51:49 | constantSalt | semmle.label | constantSalt | +| test.swift:52:49:52:49 | constantStringSalt | semmle.label | constantStringSalt | | test.swift:56:59:56:59 | constantSalt | semmle.label | constantSalt | +| test.swift:57:59:57:59 | constantStringSalt | semmle.label | constantStringSalt | | test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt | +| test.swift:63:59:63:59 | constantStringSalt | semmle.label | constantStringSalt | | test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt | +| test.swift:68:53:68:53 | constantStringSalt | semmle.label | constantStringSalt | subpaths #select | rncryptor.swift:63:57:63:57 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:63:57:63:57 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | @@ -48,6 +65,10 @@ subpaths | rncryptor.swift:78:135:78:135 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:78:135:78:135 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | | rncryptor.swift:79:160:79:160 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:79:160:79:160 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:51:49:51:49 | constantSalt | test.swift:43:35:43:130 | [...] | test.swift:51:49:51:49 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:52:49:52:49 | constantStringSalt | test.swift:29:3:29:3 | this string is constant | test.swift:52:49:52:49 | constantStringSalt | The value 'this string is constant' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:56:59:56:59 | constantSalt | test.swift:43:35:43:130 | [...] | test.swift:56:59:56:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:57:59:57:59 | constantStringSalt | test.swift:29:3:29:3 | this string is constant | test.swift:57:59:57:59 | constantStringSalt | The value 'this string is constant' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:62:59:62:59 | constantSalt | test.swift:43:35:43:130 | [...] | test.swift:62:59:62:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:63:59:63:59 | constantStringSalt | test.swift:29:3:29:3 | this string is constant | test.swift:63:59:63:59 | constantStringSalt | The value 'this string is constant' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:67:53:67:53 | constantSalt | test.swift:43:35:43:130 | [...] | test.swift:67:53:67:53 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:68:53:68:53 | constantStringSalt | test.swift:29:3:29:3 | this string is constant | test.swift:68:53:68:53 | constantStringSalt | The value 'this string is constant' is used as a constant salt, which is insecure for hashing passwords. | diff --git a/swift/ql/test/query-tests/Security/CWE-760/test.swift b/swift/ql/test/query-tests/Security/CWE-760/test.swift index 05f5396d244..434e2daf6da 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/test.swift +++ b/swift/ql/test/query-tests/Security/CWE-760/test.swift @@ -46,25 +46,25 @@ func test() { let randomArray = getRandomArray() let variant = Variant.sha2 let iterations = 120120 - + // HKDF test cases let hkdfb1 = HKDF(password: randomArray, salt: constantSalt, info: randomArray, keyLength: 0, variant: variant) // BAD - let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // BAD [NOT DETECTED] + let hkdfb2 = HKDF(password: randomArray, salt: constantStringSalt, info: randomArray, keyLength: 0, variant: variant) // BAD let hkdfg1 = HKDF(password: randomArray, salt: randomSalt, info: randomArray, keyLength: 0, variant: variant) // GOOD // PBKDF1 test cases let pbkdf1b1 = PKCS5.PBKDF1(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD - let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD [NOT DETECTED] + let pbkdf1b2 = PKCS5.PBKDF1(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD let pbkdf1g1 = PKCS5.PBKDF1(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD // PBKDF2 test cases let pbkdf2b1 = PKCS5.PBKDF2(password: randomArray, salt: constantSalt, iterations: iterations, keyLength: 0) // BAD - let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD [NOT DETECTED] + let pbkdf2b2 = PKCS5.PBKDF2(password: randomArray, salt: constantStringSalt, iterations: iterations, keyLength: 0) // BAD let pbkdf2g1 = PKCS5.PBKDF2(password: randomArray, salt: randomSalt, iterations: iterations, keyLength: 0) // GOOD // Scrypt test cases let scryptb1 = Scrypt(password: randomArray, salt: constantSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD - let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD [NOT DETECTED] + let scryptb2 = Scrypt(password: randomArray, salt: constantStringSalt, dkLen: 64, N: 16384, r: 8, p: 1) // BAD let scryptg1 = Scrypt(password: randomArray, salt: randomSalt, dkLen: 64, N: 16384, r: 8, p: 1) // GOOD -} \ No newline at end of file +}