+
+Code that passes user input directly to
+Invoke-Expression, &, or some other library
+routine that executes a command, allows the user to execute malicious
+code.
+
+The following are considered dangerous sinks:
+
+ - Invoke-Expression
+ - InvokeScript
+ - CreateNestedPipeline
+ - AddScript
+ - powershell
+ - cmd
+ - Foreach-Object
+ - Invoke
+ - CreateScriptBlock
+ - NewScriptBlock
+ - ExpandString
+
+
+
+
+
+If possible, use hard-coded string literals to specify the command to run
+or library to load. Instead of passing the user input directly to the
+process or library function, examine the user input and then choose
+among hard-coded string literals.
+
+If the applicable libraries or commands cannot be determined at
+compile time, then add code to verify that the user input string is
+safe before using it.
+
+
+
+
+The following example shows code that takes a shell script that can be changed
+maliciously by a user, and passes it straight to Invoke-Expression
+without examining it first.
+
+
+
+
+
+
+
+OWASP:
+Command Injection.
+
+
+Injection Hunter:
+PowerShell Injection Hunter: Security Auditing for PowerShell Scripts.
+
+
+
+
+
+
diff --git a/powershell/ql/src/queries/security/cwe-078/CommandInjectionCritical.ql b/powershell/ql/src/queries/security/cwe-078/CommandInjectionCritical.ql
new file mode 100644
index 000000000000..c83fb4ed98d6
--- /dev/null
+++ b/powershell/ql/src/queries/security/cwe-078/CommandInjectionCritical.ql
@@ -0,0 +1,59 @@
+/**
+ * @name Uncontrolled command line from param to CmdletBinding
+ * @description Using externally controlled strings in a command line 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 powershell/microsoft/public/command-injection-critical
+ * @tags correctness
+ * security
+ * external/cwe/cwe-078
+ * external/cwe/cwe-088
+ */
+
+import powershell
+import semmle.code.powershell.security.CommandInjectionCustomizations::CommandInjection
+import semmle.code.powershell.dataflow.TaintTracking
+import semmle.code.powershell.dataflow.DataFlow
+
+abstract class CriticalSource extends DataFlow::Node {
+ /** Gets a string that describes the type of this flow source. */
+ abstract string getSourceType();
+}
+
+class CmdletBindingParam extends CriticalSource {
+ CmdletBindingParam(){
+ exists(Attribute a, Function f |
+ a.getName() = "CmdletBinding" and
+ f = a.getEnclosingFunction() and
+ this.asParameter() = f.getAParameter()
+ )
+ }
+ override string getSourceType(){
+ result = "param to CmdletBinding function"
+ }
+}
+
+
+private module Config implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) { source instanceof CriticalSource }
+
+ predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
+
+ predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
+}
+
+/**
+ * Taint-tracking for reasoning about command-injection vulnerabilities.
+ */
+module CommandInjectionCriticalFlow = TaintTracking::Global