mirror of
https://github.com/github/codeql.git
synced 2026-05-25 00:27:09 +02:00
PS: Add 'powershell/command-injection' query.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for reasoning about
|
||||
* command-injection vulnerabilities, as well as extension points for
|
||||
* adding your own.
|
||||
*/
|
||||
|
||||
private import semmle.code.powershell.dataflow.DataFlow
|
||||
private import semmle.code.powershell.dataflow.flowsources.FlowSources
|
||||
private import semmle.code.powershell.Cfg
|
||||
|
||||
module CommandInjection {
|
||||
/**
|
||||
* A data flow source for command-injection vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this flow source. */
|
||||
abstract string getSourceType();
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink for command-injection vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for command-injection vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of user input, considered as a flow source for command injection. */
|
||||
class FlowSourceAsSource extends Source instanceof SourceNode {
|
||||
override string getSourceType() { result = "user-provided value" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A command argument to a function that initiates an operating system command.
|
||||
*/
|
||||
class SystemCommandExecutionSink extends Sink {
|
||||
SystemCommandExecutionSink() {
|
||||
// An argument to a call
|
||||
exists(DataFlow::CallNode call |
|
||||
call.getName() = "Invoke-Expression"
|
||||
or
|
||||
call instanceof DataFlow::CallOperatorNode
|
||||
|
|
||||
call.getAnArgument() = this
|
||||
)
|
||||
or
|
||||
// Or the call command itself in case it's a use of operator &.
|
||||
any(DataFlow::CallOperatorNode call).getCommand() = this
|
||||
}
|
||||
}
|
||||
|
||||
private class ExternalCommandInjectionSink extends Sink {
|
||||
ExternalCommandInjectionSink() {
|
||||
this = ModelOutput::getASinkNode("command-injection").asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Provides a taint tracking configuration for reasoning about
|
||||
* command-injection vulnerabilities (CWE-078).
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `CommandInjectionFlow` is needed, otherwise
|
||||
* `CommandInjectionCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
import powershell
|
||||
import semmle.code.powershell.dataflow.TaintTracking
|
||||
import CommandInjectionCustomizations::CommandInjection
|
||||
import semmle.code.powershell.dataflow.DataFlow
|
||||
|
||||
private module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
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 CommandInjectionFlow = TaintTracking::Global<Config>;
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @name Uncontrolled command line
|
||||
* @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/command-injection
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-078
|
||||
* external/cwe/cwe-088
|
||||
*/
|
||||
|
||||
import powershell
|
||||
import semmle.code.powershell.security.CommandInjectionQuery
|
||||
import CommandInjectionFlow::PathGraph
|
||||
|
||||
from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, Source sourceNode
|
||||
where
|
||||
CommandInjectionFlow::flowPath(source, sink) and
|
||||
sourceNode = source.getNode()
|
||||
select sink.getNode(), source, sink, "This command depends on a $@.", sourceNode,
|
||||
sourceNode.getSourceType()
|
||||
Reference in New Issue
Block a user