Python: Autoformat Command.qll

This commit is contained in:
Rasmus Wriedt Larsen
2020-03-24 10:11:57 +01:00
parent b567205579
commit 4b8020b98d

View File

@@ -1,12 +1,12 @@
/** Provides class and predicates to track external data that
/**
* Provides class and predicates to track external data that
* may represent malicious OS commands.
*
* This module is intended to be imported into a taint-tracking query
* to extend `TaintKind` and `TaintSink`.
*
*/
import python
import python
import semmle.python.security.TaintTracking
import semmle.python.security.strings.Untrusted
@@ -19,8 +19,7 @@ private ModuleObject osOrPopenModule() {
}
private Object makeOsCall() {
exists(string name |
result = ModuleObject::named("subprocess").attr(name) |
exists(string name | result = ModuleObject::named("subprocess").attr(name) |
name = "Popen" or
name = "call" or
name = "check_call" or
@@ -31,40 +30,27 @@ private Object makeOsCall() {
/**Special case for first element in sequence. */
class FirstElementKind extends TaintKind {
FirstElementKind() { this = "sequence[" + any(ExternalStringKind key) + "][0]" }
FirstElementKind() {
this = "sequence[" + any(ExternalStringKind key) + "][0]"
}
override string repr() {
result = "first item in sequence of " + this.getItem().repr()
}
override string repr() { result = "first item in sequence of " + this.getItem().repr() }
/** Gets the taint kind for item in this sequence. */
ExternalStringKind getItem() {
this = "sequence[" + result + "][0]"
}
ExternalStringKind getItem() { this = "sequence[" + result + "][0]" }
}
class FirstElementFlow extends DataFlowExtension::DataFlowNode {
FirstElementFlow() { this = any(SequenceNode s).getElement(0) }
FirstElementFlow() {
this = any(SequenceNode s).getElement(0)
}
override
ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
result.(SequenceNode).getElement(0) = this and tokind.(FirstElementKind).getItem() = fromkind
}
}
/** A taint sink that is potentially vulnerable to malicious shell commands.
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `subprocess.call(shell=vuln)` and similar calls.
*/
class ShellCommand extends CommandSink {
override string toString() { result = "shell command" }
ShellCommand() {
@@ -77,7 +63,8 @@ class ShellCommand extends CommandSink {
or
exists(CallNode call, string name |
call.getAnArg() = this and
call.getFunction().refersTo(osOrPopenModule().attr(name)) |
call.getFunction().refersTo(osOrPopenModule().attr(name))
|
name = "system" or
name = "popen" or
name.matches("popen_")
@@ -96,19 +83,18 @@ class ShellCommand extends CommandSink {
/* List (or tuple) containing a tainted string command */
kind instanceof ExternalStringSequenceKind
}
}
/** A taint sink that is potentially vulnerable to malicious shell commands.
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `subprocess.call(vuln, ...)` and similar calls.
*/
class OsCommandFirstArgument extends CommandSink {
override string toString() { result = "OS command first argument" }
OsCommandFirstArgument() {
not this instanceof ShellCommand and
exists(CallNode call|
exists(CallNode call |
call.getFunction().refersTo(makeOsCall()) and
call.getArg(0) = this
)
@@ -121,7 +107,6 @@ class OsCommandFirstArgument extends CommandSink {
/* List (or tuple) whose first element is tainted */
kind instanceof FirstElementKind
}
}
// -------------------------------------------------------------------------- //
@@ -130,8 +115,8 @@ class OsCommandFirstArgument extends CommandSink {
// Since fabric build so closely upon invoke, we model them together to avoid
// duplication
// -------------------------------------------------------------------------- //
/** A taint sink that is potentially vulnerable to malicious shell commands.
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `invoke.run(vuln, ...)` and similar calls.
*/
class InvokeRun extends CommandSink {
@@ -143,12 +128,11 @@ class InvokeRun extends CommandSink {
override string toString() { result = "InvokeRun" }
override predicate sinks(TaintKind kind) {
kind instanceof ExternalStringKind
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/** Internal TaintKind to track the invoke.Context instance passed to functions
/**
* Internal TaintKind to track the invoke.Context instance passed to functions
* marked with @invoke.task
*/
private class InvokeContextArg extends TaintKind {
@@ -164,7 +148,6 @@ private class InvokeContextArgSource extends TaintSource {
decorator = f.getADecorator() and not decorator instanceof Call
or
decorator = f.getADecorator().(Call).getFunc()
) and
(
decorator.pointsTo(Value::named("invoke.task"))
@@ -176,12 +159,11 @@ private class InvokeContextArgSource extends TaintSource {
)
}
override predicate isSourceOf(TaintKind kind) {
kind instanceof InvokeContextArg
}
override predicate isSourceOf(TaintKind kind) { kind instanceof InvokeContextArg }
}
/** A taint sink that is potentially vulnerable to malicious shell commands.
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `invoke.Context().run(vuln, ...)` and similar calls.
*/
class InvokeContextRun extends CommandSink {
@@ -195,7 +177,8 @@ class InvokeContextRun extends CommandSink {
// since fabric.Connection.run has a decorator, it doesn't work with FunctionValue :|
// and `Value::named("fabric.Connection").(ClassValue).lookup("run").getACall()` returned no results,
// so here is the hacky solution that works :\
call.getFunction().(AttrNode).getObject("run").pointsTo().getClass() = Value::named("fabric.Connection")
call.getFunction().(AttrNode).getObject("run").pointsTo().getClass() =
Value::named("fabric.Connection")
|
this = call.getArg(0)
or
@@ -205,38 +188,33 @@ class InvokeContextRun extends CommandSink {
override string toString() { result = "InvokeContextRun" }
override predicate sinks(TaintKind kind) {
kind instanceof ExternalStringKind
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/** A taint sink that is potentially vulnerable to malicious shell commands.
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `fabric.Group().run(vuln, ...)` and similar calls.
*/
class FabricGroupRun extends CommandSink {
FabricGroupRun() {
exists(ClassValue cls |
cls.getASuperType() = Value::named("fabric.Group") and
cls.getASuperType() = Value::named("fabric.Group") and
this = cls.lookup("run").(FunctionValue).getArgumentForCall(_, 1)
)
}
override string toString() { result = "FabricGroupRun" }
override predicate sinks(TaintKind kind) {
kind instanceof ExternalStringKind
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
// -------------------------------------------------------------------------- //
// Modeling of the 'invoke' package and 'fabric' package (v 1.x)
// -------------------------------------------------------------------------- //
class FabricV1Commands extends CommandSink {
FabricV1Commands() {
// since `run` and `sudo` are decorated, we can't use FunctionValue's :(
exists(CallNode call
|
exists(CallNode call |
call = Value::named("fabric.api.local").getACall()
or
call = Value::named("fabric.api.run").getACall()
@@ -251,7 +229,5 @@ class FabricV1Commands extends CommandSink {
override string toString() { result = "FabricV1Commands" }
override predicate sinks(TaintKind kind) {
kind instanceof ExternalStringKind
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}