Skip to content

Commit 416b731

Browse files
committed
Swift: Model NSUserScriptTask sinks.
1 parent 7177189 commit 416b731

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ private class CommandInjectionSinks extends SinkModelCsv {
6464
";Process;true;standardOutput;;;PostUpdate;command-injection",
6565
";Process;true;currentDirectoryPath;;;PostUpdate;command-injection",
6666
";Process;true;launchPath;;;PostUpdate;command-injection",
67+
";NSUserScriptTask;true;init(url:);;;Argument[0];command-injection",
68+
";NSUserUnixTask;true;execute(withArguments:completionHandler:);;;Argument[0];command-injection",
6769
]
6870
}
6971
}

swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ edges
6363
| CommandInjection.swift:146:23:146:55 | call to URL.init(string:) [some:0] | CommandInjection.swift:146:23:146:56 | ...! |
6464
| CommandInjection.swift:146:35:146:35 | userControlledString | CommandInjection.swift:146:23:146:55 | call to URL.init(string:) [some:0] |
6565
| CommandInjection.swift:147:70:147:70 | userControlledString | CommandInjection.swift:147:62:147:90 | [...] |
66+
| CommandInjection.swift:147:70:147:70 | userControlledString | CommandInjection.swift:152:53:152:53 | userControlledString |
67+
| CommandInjection.swift:147:70:147:70 | userControlledString | CommandInjection.swift:155:52:155:52 | userControlledString |
68+
| CommandInjection.swift:147:70:147:70 | userControlledString | CommandInjection.swift:156:33:156:33 | userControlledString |
69+
| CommandInjection.swift:152:41:152:73 | call to URL.init(string:) [some:0] | CommandInjection.swift:152:41:152:74 | ...! |
70+
| CommandInjection.swift:152:53:152:53 | userControlledString | CommandInjection.swift:152:41:152:73 | call to URL.init(string:) [some:0] |
71+
| CommandInjection.swift:155:40:155:72 | call to URL.init(string:) [some:0] | CommandInjection.swift:155:40:155:73 | ...! |
72+
| CommandInjection.swift:155:40:155:72 | call to URL.init(string:) [some:0] | CommandInjection.swift:155:40:155:73 | ...! |
73+
| CommandInjection.swift:155:40:155:73 | ...! | file://:0:0:0:0 | url |
74+
| CommandInjection.swift:155:52:155:52 | userControlledString | CommandInjection.swift:155:40:155:72 | call to URL.init(string:) [some:0] |
75+
| CommandInjection.swift:156:33:156:33 | userControlledString | CommandInjection.swift:156:32:156:53 | [...] |
76+
| CommandInjection.swift:156:33:156:33 | userControlledString | CommandInjection.swift:158:57:158:57 | userControlledString |
77+
| CommandInjection.swift:158:45:158:77 | call to URL.init(string:) [some:0] | CommandInjection.swift:158:45:158:78 | ...! |
78+
| CommandInjection.swift:158:45:158:77 | call to URL.init(string:) [some:0] | CommandInjection.swift:158:45:158:78 | ...! |
79+
| CommandInjection.swift:158:45:158:78 | ...! | file://:0:0:0:0 | url |
80+
| CommandInjection.swift:158:57:158:57 | userControlledString | CommandInjection.swift:158:45:158:77 | call to URL.init(string:) [some:0] |
81+
| file://:0:0:0:0 | url | file://:0:0:0:0 | url |
82+
| file://:0:0:0:0 | url | file://:0:0:0:0 | url |
6683
nodes
6784
| CommandInjection.swift:58:22:58:33 | command | semmle.label | command |
6885
| CommandInjection.swift:58:22:58:33 | command [some:0] | semmle.label | command [some:0] |
@@ -129,6 +146,23 @@ nodes
129146
| CommandInjection.swift:146:35:146:35 | userControlledString | semmle.label | userControlledString |
130147
| CommandInjection.swift:147:62:147:90 | [...] | semmle.label | [...] |
131148
| CommandInjection.swift:147:70:147:70 | userControlledString | semmle.label | userControlledString |
149+
| CommandInjection.swift:152:41:152:73 | call to URL.init(string:) [some:0] | semmle.label | call to URL.init(string:) [some:0] |
150+
| CommandInjection.swift:152:41:152:74 | ...! | semmle.label | ...! |
151+
| CommandInjection.swift:152:53:152:53 | userControlledString | semmle.label | userControlledString |
152+
| CommandInjection.swift:155:40:155:72 | call to URL.init(string:) [some:0] | semmle.label | call to URL.init(string:) [some:0] |
153+
| CommandInjection.swift:155:40:155:73 | ...! | semmle.label | ...! |
154+
| CommandInjection.swift:155:40:155:73 | ...! | semmle.label | ...! |
155+
| CommandInjection.swift:155:52:155:52 | userControlledString | semmle.label | userControlledString |
156+
| CommandInjection.swift:156:32:156:53 | [...] | semmle.label | [...] |
157+
| CommandInjection.swift:156:33:156:33 | userControlledString | semmle.label | userControlledString |
158+
| CommandInjection.swift:158:45:158:77 | call to URL.init(string:) [some:0] | semmle.label | call to URL.init(string:) [some:0] |
159+
| CommandInjection.swift:158:45:158:78 | ...! | semmle.label | ...! |
160+
| CommandInjection.swift:158:45:158:78 | ...! | semmle.label | ...! |
161+
| CommandInjection.swift:158:57:158:57 | userControlledString | semmle.label | userControlledString |
162+
| file://:0:0:0:0 | url | semmle.label | url |
163+
| file://:0:0:0:0 | url | semmle.label | url |
164+
| file://:0:0:0:0 | url | semmle.label | url |
165+
| file://:0:0:0:0 | url | semmle.label | url |
132166
subpaths
133167
| CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] |
134168
| CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:58:22:58:33 | command [some:0] | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] |
@@ -145,3 +179,9 @@ subpaths
145179
| CommandInjection.swift:143:67:143:95 | [...] | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:143:67:143:95 | [...] | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
146180
| CommandInjection.swift:146:23:146:56 | ...! | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:146:23:146:56 | ...! | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
147181
| CommandInjection.swift:147:62:147:90 | [...] | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:147:62:147:90 | [...] | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
182+
| CommandInjection.swift:152:41:152:74 | ...! | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:152:41:152:74 | ...! | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
183+
| CommandInjection.swift:155:40:155:73 | ...! | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:155:40:155:73 | ...! | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
184+
| CommandInjection.swift:156:32:156:53 | [...] | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:156:32:156:53 | [...] | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
185+
| CommandInjection.swift:158:45:158:78 | ...! | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:158:45:158:78 | ...! | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
186+
| file://:0:0:0:0 | url | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | file://:0:0:0:0 | url | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |
187+
| file://:0:0:0:0 | url | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | file://:0:0:0:0 | url | This command depends on a $@. | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | user-provided value |

swift/ql/test/query-tests/Security/CWE-078/CommandInjection.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ func testCommandInjectionMore(mySafeString: String) {
149149
let task8 = try! NSUserScriptTask(url: URL(string: mySafeString)!) // GOOD
150150
task8.execute()
151151

152-
let task9 = try! NSUserScriptTask(url: URL(string: userControlledString)!) // BAD [NOT DETECTED]
152+
let task9 = try! NSUserScriptTask(url: URL(string: userControlledString)!) // BAD
153153
task9.execute()
154154

155-
let task10 = try! NSUserUnixTask(url: URL(string: userControlledString)!) // BAD [NOT DETECTED]
156-
task10.execute(withArguments: [userControlledString]) // BAD [NOT DETECTED]
155+
let task10 = try! NSUserUnixTask(url: URL(string: userControlledString)!) // BAD
156+
task10.execute(withArguments: [userControlledString]) // BAD
157157

158-
let task11 = try! NSUserAutomatorTask(url: URL(string: userControlledString)!) // BAD [NOT DETECTED]
158+
let task11 = try! NSUserAutomatorTask(url: URL(string: userControlledString)!) // BAD
159159
task11.variables = ["abc": userControlledString] // BAD [NOT DETECTED]
160160
task11.execute(withInput: nil)
161161
}

0 commit comments

Comments
 (0)