+
+
+
+Constructing a system command with unsanitized user input is dangerous,
+since a malicious user may be able to craft input that executes arbitrary code.
+
+
+
+
+
+If possible, use hard-coded string literals to specify the command to run. Instead of interpreting
+user input directly as command names, examine the input and then choose among hard-coded string
+literals.
+
+
+If this is not possible, then add sanitization code to verify that the user input is safe before
+using it.
+
+
+
+
+
+The following example executes code from user input without
+sanitizing it first:
+
+
+
+If user input is used to construct a command it should be checked
+first. This ensures that the user cannot insert characters that have special
+meanings:
+
+
+
+
+
+
+OWASP:
+Command Injection.
+
+
+
diff --git a/unified/ql/src/queries/security/CWE-078/CommandInjection.ql b/unified/ql/src/queries/security/CWE-078/CommandInjection.ql
new file mode 100644
index 000000000000..c1268d2bde21
--- /dev/null
+++ b/unified/ql/src/queries/security/CWE-078/CommandInjection.ql
@@ -0,0 +1,43 @@
+/**
+ * @name System command built from user-controlled sources
+ * @description Building a system command from user-controlled sources may allow a malicious
+ * user to change the meaning of the command.
+ * @kind path-problem
+ * @problem.severity error
+ * @security-severity 9.8
+ * @precision high
+ * @id unified/swift/command-line-injection
+ * @tags security
+ * external/cwe/cwe-078
+ * external/cwe/cwe-088
+ */
+
+import unified
+
+/**
+ * A taint configuration for tainted data that reaches a command injection sink.
+ */
+module CommandInjectionConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node node) { Models::isSource(node, _) }
+
+ predicate isSink(DataFlow::Node node) {
+ // TODO: Support Process property-write sinks from original Swift's CommandInjectionExtensions.qll.
+ Models::isSink(node, "command-injection")
+ }
+
+ predicate isBarrier(DataFlow::Node node) {
+ // TODO: Port the numeric-type barrier from original Swift's CommandInjectionExtensions.qll.
+ none()
+ }
+
+ predicate observeDiffInformedIncrementalMode() { any() }
+}
+
+module CommandInjectionFlow = TaintTracking::Global