mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Python: Autoformat Command.qll
This commit is contained in:
@@ -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 }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user