Merge pull request #13342 from erik-krogh/once-again-deps

Py: delete more old deprecations
This commit is contained in:
Erik Krogh Kristensen
2023-06-20 15:29:17 +02:00
committed by GitHub
99 changed files with 42 additions and 3361 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Deleted many models that used the old dataflow library, the new models can be found in the `python/ql/lib/semmle/python/frameworks` folder.

View File

@@ -664,6 +664,14 @@ module DataFlow {
}
}
deprecated private class DataFlowType extends TaintKind {
// this only exists to avoid an empty recursion error in the type checker
DataFlowType() {
this = "Data flow" and
1 = 2
}
}
pragma[noinline]
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {
dictnode.(DictNode).getAValue() = itemnode

View File

@@ -1,103 +0,0 @@
/**
* Provides classes and predicates for tracking exceptions and information
* associated with exceptions.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
deprecated private Value traceback_function(string name) {
result = Module::named("traceback").attr(name)
}
/**
* This represents information relating to an exception, for instance the
* message, arguments or parts of the exception traceback.
*/
deprecated class ExceptionInfo extends StringKind {
ExceptionInfo() { this = "exception.info" }
override string repr() { result = "exception info" }
}
/**
* A class representing sources of information about
* execution state exposed in tracebacks and the like.
*/
abstract deprecated class ErrorInfoSource extends TaintSource { }
/**
* This kind represents exceptions themselves.
*/
deprecated class ExceptionKind extends TaintKind {
ExceptionKind() { this = "exception.kind" }
override string repr() { result = "exception" }
override TaintKind getTaintOfAttribute(string name) {
name = "args" and result instanceof ExceptionInfoSequence
or
name = "message" and result instanceof ExceptionInfo
}
}
/**
* A source of exception objects, either explicitly created, or captured by an
* `except` statement.
*/
deprecated class ExceptionSource extends ErrorInfoSource {
ExceptionSource() {
exists(ClassValue cls |
cls.getASuperType() = ClassValue::baseException() and
this.(ControlFlowNode).pointsTo().getClass() = cls
)
or
this = any(ExceptStmt s).getName().getAFlowNode()
}
override string toString() { result = "exception.source" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionKind }
}
/**
* Represents a sequence of pieces of information relating to an exception,
* for instance the contents of the `args` attribute, or the stack trace.
*/
deprecated class ExceptionInfoSequence extends SequenceKind {
ExceptionInfoSequence() { this.getItem() instanceof ExceptionInfo }
}
/**
* Represents calls to functions in the `traceback` module that return
* sequences of exception information.
*/
deprecated class CallToTracebackFunction extends ErrorInfoSource {
CallToTracebackFunction() {
exists(string name |
name in [
"extract_tb", "extract_stack", "format_list", "format_exception_only", "format_exception",
"format_tb", "format_stack"
]
|
this = traceback_function(name).getACall()
)
}
override string toString() { result = "exception.info.sequence.source" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfoSequence }
}
/**
* Represents calls to functions in the `traceback` module that return a single
* string of information about an exception.
*/
deprecated class FormattedTracebackSource extends ErrorInfoSource {
FormattedTracebackSource() { this = traceback_function("format_exc").getACall() }
override string toString() { result = "exception.info.source" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo }
}

View File

@@ -1,4 +1,4 @@
import python
import semmle.python.dataflow.TaintTracking
abstract class SqlInjectionSink extends TaintSink { }
abstract deprecated class SqlInjectionSink extends TaintSink { }

View File

@@ -1,263 +0,0 @@
/**
* 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 semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
/** Abstract taint sink that is potentially vulnerable to malicious shell commands. */
abstract deprecated class CommandSink extends TaintSink { }
deprecated private ModuleObject osOrPopenModule() { result.getName() = ["os", "popen2"] }
deprecated private Object makeOsCall() {
exists(string name | result = ModuleObject::named("subprocess").attr(name) |
name = ["Popen", "call", "check_call", "check_output", "run"]
)
}
/**Special case for first element in sequence. */
deprecated class FirstElementKind extends TaintKind {
FirstElementKind() { this = "sequence[" + any(ExternalStringKind key) + "][0]" }
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]" }
}
deprecated class FirstElementFlow extends DataFlowExtension::DataFlowNode {
FirstElementFlow() { this = any(SequenceNode s).getElement(0) }
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.
* The `vuln` in `subprocess.call(shell=vuln)` and similar calls.
*/
deprecated class ShellCommand extends CommandSink {
override string toString() { result = "shell command" }
ShellCommand() {
exists(CallNode call, Object istrue |
call.getFunction().refersTo(makeOsCall()) and
call.getAnArg() = this and
call.getArgByName("shell").refersTo(istrue) and
istrue.booleanValue() = true
)
or
exists(CallNode call, string name |
call.getAnArg() = this and
call.getFunction().refersTo(osOrPopenModule().attr(name))
|
name = ["system", "popen"] or
name.matches("popen_")
)
or
exists(CallNode call |
call.getAnArg() = this and
call.getFunction().refersTo(ModuleObject::named("commands"))
)
}
override predicate sinks(TaintKind kind) {
/* Tainted string command */
kind instanceof ExternalStringKind
or
/* List (or tuple) containing a tainted string command */
kind instanceof ExternalStringSequenceKind
}
}
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `subprocess.call(vuln, ...)` and similar calls.
*/
deprecated class OsCommandFirstArgument extends CommandSink {
override string toString() { result = "OS command first argument" }
OsCommandFirstArgument() {
not this instanceof ShellCommand and
exists(CallNode call |
call.getFunction().refersTo(makeOsCall()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) {
/* Tainted string command */
kind instanceof ExternalStringKind
or
/* List (or tuple) whose first element is tainted */
kind instanceof FirstElementKind
}
}
// -------------------------------------------------------------------------- //
// Modeling of the 'invoke' package and 'fabric' package (v 2.x)
//
// 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.
* The `vuln` in `invoke.run(vuln, ...)` and similar calls.
*/
deprecated class InvokeRun extends CommandSink {
InvokeRun() {
this = Value::named("invoke.run").(FunctionValue).getArgumentForCall(_, 0)
or
this = Value::named("invoke.sudo").(FunctionValue).getArgumentForCall(_, 0)
}
override string toString() { result = "InvokeRun" }
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* Internal TaintKind to track the invoke.Context instance passed to functions
* marked with @invoke.task
*/
deprecated private class InvokeContextArg extends TaintKind {
InvokeContextArg() { this = "InvokeContextArg" }
}
/** Internal TaintSource to track the context passed to functions marked with @invoke.task */
deprecated private class InvokeContextArgSource extends TaintSource {
InvokeContextArgSource() {
exists(Function f, Expr decorator |
count(f.getADecorator()) = 1 and
(
decorator = f.getADecorator() and not decorator instanceof Call
or
decorator = f.getADecorator().(Call).getFunc()
) and
(
decorator.pointsTo(Value::named("invoke.task"))
or
decorator.pointsTo(Value::named("fabric.task"))
)
|
this.(ControlFlowNode).getNode() = f.getArg(0)
)
}
override predicate isSourceOf(TaintKind kind) { kind instanceof InvokeContextArg }
}
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `invoke.Context().run(vuln, ...)` and similar calls.
*/
deprecated class InvokeContextRun extends CommandSink {
InvokeContextRun() {
exists(CallNode call |
any(InvokeContextArg k).taints(call.getFunction().(AttrNode).getObject("run"))
or
call = Value::named("invoke.Context").(ClassValue).lookup("run").getACall()
or
// fabric.connection.Connection is a subtype of invoke.context.Context
// 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")
|
this = call.getArg(0)
or
this = call.getArgByName("command")
)
}
override string toString() { result = "InvokeContextRun" }
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `fabric.Group().run(vuln, ...)` and similar calls.
*/
deprecated class FabricGroupRun extends CommandSink {
FabricGroupRun() {
exists(ClassValue cls |
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 }
}
// -------------------------------------------------------------------------- //
// Modeling of the 'invoke' package and 'fabric' package (v 1.x)
// -------------------------------------------------------------------------- //
deprecated class FabricV1Commands extends CommandSink {
FabricV1Commands() {
// since `run` and `sudo` are decorated, we can't use FunctionValue's :(
exists(CallNode call |
call = Value::named("fabric.api.local").getACall()
or
call = Value::named("fabric.api.run").getACall()
or
call = Value::named("fabric.api.sudo").getACall()
|
this = call.getArg(0)
or
this = call.getArgByName("command")
)
}
override string toString() { result = "FabricV1Commands" }
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* An extension that propagates taint from the arguments of `fabric.api.execute(func, arg0, arg1, ...)`
* to the parameters of `func`, since this will call `func(arg0, arg1, ...)`.
*/
deprecated class FabricExecuteExtension extends DataFlowExtension::DataFlowNode {
CallNode call;
FabricExecuteExtension() {
call = Value::named("fabric.api.execute").getACall() and
(
this = call.getArg(any(int i | i > 0))
or
this = call.getArgByName(any(string s | not s = "task"))
)
}
override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
tokind = fromkind and
exists(CallableValue func |
(
call.getArg(0).pointsTo(func)
or
call.getArgByName("task").pointsTo(func)
) and
exists(int i |
// execute(func, arg0, arg1) => func(arg0, arg1)
this = call.getArg(i) and
result = func.getParameter(i - 1)
)
or
exists(string name |
this = call.getArgByName(name) and
result = func.getParameterByName(name)
)
)
}
}

View File

@@ -1,83 +0,0 @@
/**
* Provides class and predicates to track external data that
* may represent malicious SQL queries or parts of queries.
*
* This module is intended to be imported into a taint-tracking query
* to extend `TaintKind` and `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.SQL
deprecated private StringObject first_part(ControlFlowNode command) {
command.(BinaryExprNode).getOp() instanceof Add and
command.(BinaryExprNode).getLeft().refersTo(result)
or
exists(CallNode call, SequenceObject seq | call = command |
call = theStrType().lookupAttribute("join") and
call.getArg(0).refersTo(seq) and
seq.getInferredElement(0) = result
)
or
command.(BinaryExprNode).getOp() instanceof Mod and
command.getNode().(StrConst).getLiteralObject() = result
}
/** Holds if `command` appears to be a SQL command string of which `inject` is a part. */
deprecated predicate probable_sql_command(ControlFlowNode command, ControlFlowNode inject) {
exists(string prefix |
inject = command.getAChild*() and
first_part(command).getText().regexpMatch(" *" + prefix + ".*")
|
prefix = "CREATE" or prefix = "SELECT"
)
}
/**
* A taint kind representing a DB cursor.
* This will be overridden to provide specific kinds of DB cursor.
*/
abstract deprecated class DbCursor extends TaintKind {
bindingset[this]
DbCursor() { any() }
string getExecuteMethodName() { result = "execute" }
}
/**
* A part of a string that appears to be a SQL command and is thus
* vulnerable to malicious input.
*/
deprecated class SimpleSqlStringInjection extends SqlInjectionSink {
override string toString() { result = "simple SQL string injection" }
SimpleSqlStringInjection() { probable_sql_command(_, this) }
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* A taint source representing sources of DB connections.
* This will be overridden to provide specific kinds of DB connection sources.
*/
abstract deprecated class DbConnectionSource extends TaintSource { }
/**
* A taint sink that is vulnerable to malicious SQL queries.
* The `vuln` in `db.connection.execute(vuln)` and similar.
*/
deprecated class DbConnectionExecuteArgument extends SqlInjectionSink {
override string toString() { result = "db.connection.execute" }
DbConnectionExecuteArgument() {
exists(CallNode call, DbCursor cursor, string name |
cursor.taints(call.getFunction().(AttrNode).getObject(name)) and
cursor.getExecuteMethodName() = name and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -1,2 +0,0 @@
import semmle.python.web.client.StdLib
import semmle.python.web.client.Requests

View File

@@ -1,7 +0,0 @@
import python
import semmle.python.security.strings.Basic
import semmle.python.web.django.Redirect
import semmle.python.web.flask.Redirect
import semmle.python.web.tornado.Redirect
import semmle.python.web.pyramid.Redirect
import semmle.python.web.bottle.Redirect

View File

@@ -1,10 +0,0 @@
import semmle.python.web.django.Response
import semmle.python.web.flask.Response
import semmle.python.web.pyramid.Response
import semmle.python.web.tornado.Response
import semmle.python.web.twisted.Response
import semmle.python.web.bottle.Response
import semmle.python.web.turbogears.Response
import semmle.python.web.falcon.Response
import semmle.python.web.cherrypy.Response
import semmle.python.web.stdlib.Response

View File

@@ -1,28 +0,0 @@
/**
* Provides class representing the `bottle.redirect` function.
* This module is intended to be imported into a taint-tracking query
* to extend `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.bottle.General
deprecated FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") }
/**
* An argument to the `bottle.redirect` function.
*/
deprecated class BottleRedirect extends TaintSink {
override string toString() { result = "bottle.redirect" }
BottleRedirect() {
exists(CallNode call |
bottle_redirect().getACall() = call and
this = call.getAnArg()
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}

View File

@@ -1,52 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.web.Http
import semmle.python.web.bottle.General
/**
* A bottle.Response object
* This isn't really a "taint", but we use the value tracking machinery to
* track the flow of response objects.
*/
deprecated class BottleResponse extends TaintKind {
BottleResponse() { this = "bottle.response" }
}
deprecated private Value theBottleResponseObject() { result = theBottleModule().attr("response") }
deprecated class BottleResponseBodyAssignment extends HttpResponseTaintSink {
BottleResponseBodyAssignment() {
exists(DefinitionNode lhs |
lhs.getValue() = this and
lhs.(AttrNode).getObject("body").pointsTo(theBottleResponseObject())
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
deprecated class BottleHandlerFunctionResult extends HttpResponseTaintSink {
BottleHandlerFunctionResult() {
exists(BottleRoute route, Return ret |
ret.getScope() = route.getFunction() and
ret.getValue().getAFlowNode() = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
override string toString() { result = "bottle handler function result" }
}
deprecated class BottleCookieSet extends CookieSet, CallNode {
BottleCookieSet() {
any(BottleResponse r).taints(this.getFunction().(AttrNode).getObject("set_cookie"))
}
override string toString() { result = CallNode.super.toString() }
override ControlFlowNode getKey() { result = this.getArg(0) }
override ControlFlowNode getValue() { result = this.getArg(1) }
}

View File

@@ -1,18 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.web.Http
import semmle.python.web.cherrypy.General
deprecated class CherryPyExposedFunctionResult extends HttpResponseTaintSink {
CherryPyExposedFunctionResult() {
exists(Return ret |
ret.getScope() instanceof CherryPyExposedFunction and
ret.getValue().getAFlowNode() = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
override string toString() { result = "cherrypy handler function result" }
}

View File

@@ -1,22 +0,0 @@
/**
* Modeling outgoing HTTP requests using the `requests` package
* https://pypi.org/project/requests/
*/
import python
private import semmle.python.web.Http
deprecated class RequestsHttpRequest extends Client::HttpRequest, CallNode {
CallableValue func;
string method;
RequestsHttpRequest() {
method = httpVerbLower() and
func = Module::named("requests").attr(method) and
this = func.getACall()
}
override ControlFlowNode getAUrlPart() { result = func.getNamedArgumentForCall(this, "url") }
override string getMethodUpper() { result = method.toUpperCase() }
}

View File

@@ -1,55 +0,0 @@
import python
private import semmle.python.web.Http
deprecated ClassValue httpConnectionClass() {
// Python 2
result = Value::named("httplib.HTTPConnection")
or
result = Value::named("httplib.HTTPSConnection")
or
// Python 3
result = Value::named("http.client.HTTPConnection")
or
result = Value::named("http.client.HTTPSConnection")
or
// six
result = Value::named("six.moves.http_client.HTTPConnection")
or
result = Value::named("six.moves.http_client.HTTPSConnection")
}
deprecated class HttpConnectionHttpRequest extends Client::HttpRequest, CallNode {
CallNode constructor_call;
CallableValue func;
HttpConnectionHttpRequest() {
exists(ClassValue cls, AttrNode call_origin, Value constructor_call_value |
cls = httpConnectionClass() and
func = cls.lookup("request") and
this = func.getACall() and
// since you can do `r = conn.request; r('GET', path)`, we need to find the origin
this.getFunction().pointsTo(_, _, call_origin) and
// Since HTTPSConnection is a subtype of HTTPConnection, up until this point, `cls` could be either class,
// because `HTTPSConnection.request == HTTPConnection.request`. To avoid generating 2 results, we filter
// on the actual class used as the constructor
call_origin.getObject().pointsTo(_, constructor_call_value, constructor_call) and
cls = constructor_call_value.getClass() and
constructor_call = cls.getACall()
)
}
override ControlFlowNode getAUrlPart() {
result = func.getNamedArgumentForCall(this, "url")
or
result = constructor_call.getArg(0)
or
result = constructor_call.getArgByName("host")
}
override string getMethodUpper() {
exists(string method |
result = method.toUpperCase() and
func.getNamedArgumentForCall(this, "method").pointsTo(Value::forString(method))
)
}
}

View File

@@ -1,50 +0,0 @@
import python
import semmle.python.security.injection.Sql
/**
* A taint kind representing a django cursor object.
*/
deprecated class DjangoDbCursor extends DbCursor {
DjangoDbCursor() { this = "django.db.connection.cursor" }
}
deprecated private Value theDjangoConnectionObject() {
result = Value::named("django.db.connection")
}
/**
* A kind of taint source representing sources of django cursor objects.
*/
deprecated class DjangoDbCursorSource extends DbConnectionSource {
DjangoDbCursorSource() {
exists(AttrNode cursor |
this.(CallNode).getFunction() = cursor and
cursor.getObject("cursor").pointsTo(theDjangoConnectionObject())
)
}
override string toString() { result = "django.db.connection.cursor" }
override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoDbCursor }
}
deprecated ClassValue theDjangoRawSqlClass() {
result = Value::named("django.db.models.expressions.RawSQL")
}
/**
* A sink of taint on calls to `django.db.models.expressions.RawSQL`. This
* allows arbitrary SQL statements to be executed, which is a security risk.
*/
deprecated class DjangoRawSqlSink extends SqlInjectionSink {
DjangoRawSqlSink() {
exists(CallNode call |
call = theDjangoRawSqlClass().getACall() and
this = call.getArg(0)
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "django.db.models.expressions.RawSQL(sink,...)" }
}

View File

@@ -1,69 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
import semmle.python.security.injection.Sql
/** A django model class */
deprecated class DjangoModel extends ClassValue {
DjangoModel() { Value::named("django.db.models.Model") = this.getASuperType() }
}
/** A "taint" for django database tables */
deprecated class DjangoDbTableObjects extends TaintKind {
DjangoDbTableObjects() { this = "django.db.models.Model.objects" }
override TaintKind getTaintOfMethodResult(string name) {
result = this and
name in [
"filter", "exclude", "none", "all", "union", "intersection", "difference", "select_related",
"prefetch_related", "extra", "defer", "only", "annotate", "using", "select_for_update",
"raw", "order_by", "reverse", "distinct", "values", "values_list", "dates", "datetimes"
]
}
}
/** Django model objects, which are sources of django database table "taint" */
deprecated class DjangoModelObjects extends TaintSource {
DjangoModelObjects() {
this.(AttrNode).isLoad() and this.(AttrNode).getObject("objects").pointsTo(any(DjangoModel m))
}
override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoDbTableObjects }
override string toString() { result = "django.db.models.Model.objects" }
}
/**
* A call to the `raw` method on a django model. This allows a raw SQL query
* to be sent to the database, which is a security risk.
*/
deprecated class DjangoModelRawCall extends SqlInjectionSink {
DjangoModelRawCall() {
exists(CallNode raw_call, ControlFlowNode queryset | this = raw_call.getArg(0) |
raw_call.getFunction().(AttrNode).getObject("raw") = queryset and
any(DjangoDbTableObjects objs).taints(queryset)
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "django.models.QuerySet.raw(sink,...)" }
}
/**
* A call to the `extra` method on a django model. This allows a raw SQL query
* to be sent to the database, which is a security risk.
*/
deprecated class DjangoModelExtraCall extends SqlInjectionSink {
DjangoModelExtraCall() {
exists(CallNode extra_call, ControlFlowNode queryset | this = extra_call.getArg(0) |
extra_call.getFunction().(AttrNode).getObject("extra") = queryset and
any(DjangoDbTableObjects objs).taints(queryset)
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "django.models.QuerySet.extra(sink,...)" }
}

View File

@@ -1,37 +0,0 @@
/**
* Provides class representing the `django.redirect` function.
* This module is intended to be imported into a taint-tracking query
* to extend `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
private import semmle.python.web.django.Shared
private import semmle.python.web.Http
/**
* The URL argument for a call to the `django.shortcuts.redirect` function.
*/
deprecated class DjangoShortcutsRedirectSink extends HttpRedirectTaintSink {
override string toString() { result = "DjangoShortcutsRedirectSink" }
DjangoShortcutsRedirectSink() {
this = Value::named("django.shortcuts.redirect").(FunctionValue).getArgumentForCall(_, 0)
}
}
/**
* The URL argument when instantiating a Django Redirect Response.
*/
deprecated class DjangoRedirectResponseSink extends HttpRedirectTaintSink {
DjangoRedirectResponseSink() {
exists(CallNode call | call = any(DjangoRedirectResponseClass cls).getACall() |
this = call.getArg(0)
or
this = call.getArgByName("redirect_to")
)
}
override string toString() { result = "DjangoRedirectResponseSink" }
}

View File

@@ -1,79 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
private import semmle.python.web.django.Shared
private import semmle.python.web.Http
/** INTERNAL class used for tracking a django response object. */
deprecated private class DjangoResponseKind extends TaintKind {
DjangoResponseKind() { this = "django.response.HttpResponse" }
}
/** INTERNAL taint-source used for tracking a django response object. */
deprecated private class DjangoResponseSource extends TaintSource {
DjangoResponseSource() { exists(DjangoContentResponseClass cls | cls.getACall() = this) }
override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoResponseKind }
override string toString() { result = "django.http.response.HttpResponse" }
}
/** A write to a django response, which is vulnerable to external data (xss) */
deprecated class DjangoResponseWrite extends HttpResponseTaintSink {
DjangoResponseWrite() {
exists(AttrNode meth, CallNode call |
call.getFunction() = meth and
any(DjangoResponseKind response).taints(meth.getObject("write")) and
this = call.getArg(0)
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
override string toString() { result = "django.Response.write(...)" }
}
/**
* An argument to initialization of a django response.
*/
deprecated class DjangoResponseContent extends HttpResponseTaintSink {
DjangoContentResponseClass cls;
CallNode call;
DjangoResponseContent() {
call = cls.getACall() and
this = cls.getContentArg(call)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
override string toString() { result = "django.Response(...)" }
}
/**
* An argument to initialization of a django response, which is vulnerable to external data (XSS).
*/
deprecated class DjangoResponseContentXSSVulnerable extends DjangoResponseContent {
override DjangoXSSVulnerableResponseClass cls;
DjangoResponseContentXSSVulnerable() {
not exists(cls.getContentTypeArg(call))
or
exists(StringValue s |
cls.getContentTypeArg(call).pointsTo(s) and
s.getText().matches("text/html%")
)
}
}
deprecated class DjangoCookieSet extends CookieSet, CallNode {
DjangoCookieSet() {
any(DjangoResponseKind r).taints(this.getFunction().(AttrNode).getObject("set_cookie"))
}
override string toString() { result = CallNode.super.toString() }
override ControlFlowNode getKey() { result = this.getArg(0) }
override ControlFlowNode getValue() { result = this.getArg(1) }
}

View File

@@ -1,6 +0,0 @@
import python
/*
* Sanitizers
* No django sanitizers implemented yet.
*/

View File

@@ -1,72 +0,0 @@
import python
/** A class that is a Django Redirect Response (subclass of `django.http.HttpResponseRedirectBase`). */
deprecated class DjangoRedirectResponseClass extends ClassValue {
DjangoRedirectResponseClass() {
exists(ClassValue redirect_base |
// version 1.x
redirect_base = Value::named("django.http.response.HttpResponseRedirectBase")
or
// version 2.x and 3.x
redirect_base = Value::named("django.http.HttpResponseRedirectBase")
|
this.getASuperType() = redirect_base
)
}
}
/**
* A class that is a Django Response, which can contain content.
* A subclass of `django.http.HttpResponse` that is not a `DjangoRedirectResponseClass`.
*/
deprecated class DjangoContentResponseClass extends ClassValue {
ClassValue base;
DjangoContentResponseClass() {
(
// version 1.x
base = Value::named("django.http.response.HttpResponse")
or
// version 2.x and 3.x
// https://docs.djangoproject.com/en/2.2/ref/request-response/#httpresponse-objects
base = Value::named("django.http.HttpResponse")
) and
this.getASuperType() = base
}
// The reason these two methods are defined in this class (and not in the Sink
// definition that uses this class), is that if we were to add support for
// `django.http.response.HttpResponseNotAllowed` it would make much more sense to add
// the custom logic in this class (or subclass), than to handle all of it in the sink
// definition.
/** Gets the `content` argument of a `call` to the constructor */
ControlFlowNode getContentArg(CallNode call) { none() }
/** Gets the `content_type` argument of a `call` to the constructor */
ControlFlowNode getContentTypeArg(CallNode call) { none() }
}
/** A class that is a Django Response, and is vulnerable to XSS. */
deprecated class DjangoXSSVulnerableResponseClass extends DjangoContentResponseClass {
DjangoXSSVulnerableResponseClass() {
// We want to avoid FPs on subclasses that are not exposed to XSS, for example `JsonResponse`.
// The easiest way is to disregard any subclass that has a special `__init__` method.
// It's not guaranteed to remove all FPs, or not to generate FNs, but compared to our
// previous implementation that would treat 0-th argument to _any_ subclass as a sink,
// this gets us much closer to reality.
this.lookup("__init__") = base.lookup("__init__") and
not this instanceof DjangoRedirectResponseClass
}
override ControlFlowNode getContentArg(CallNode call) {
result = call.getArg(0)
or
result = call.getArgByName("content")
}
override ControlFlowNode getContentTypeArg(CallNode call) {
result = call.getArg(1)
or
result = call.getArgByName("content_type")
}
}

View File

@@ -1,28 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
import semmle.python.web.falcon.General
/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */
deprecated class FalconResponse extends TaintKind {
FalconResponse() { this = "falcon.response" }
}
/** Only used internally to track the response parameter */
deprecated private class FalconResponseParameter extends TaintSource {
FalconResponseParameter() {
exists(FalconHandlerFunction f | f.getResponse() = this.(ControlFlowNode).getNode())
}
override predicate isSourceOf(TaintKind k) { k instanceof FalconResponse }
}
deprecated class FalconResponseBodySink extends HttpResponseTaintSink {
FalconResponseBodySink() {
exists(AttrNode attr | any(FalconResponse f).taints(attr.getObject("body")) |
attr.(DefinitionNode).getValue() = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}

View File

@@ -1,26 +0,0 @@
/**
* Provides class representing the `flask.redirect` function.
* This module is intended to be imported into a taint-tracking query
* to extend `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.flask.General
deprecated FunctionValue flask_redirect() { result = Value::named("flask.redirect") }
/**
* Represents an argument to the `flask.redirect` function.
*/
deprecated class FlaskRedirect extends HttpRedirectTaintSink {
override string toString() { result = "flask.redirect" }
FlaskRedirect() {
exists(CallNode call |
flask_redirect().getACall() = call and
this = call.getAnArg()
)
}
}

View File

@@ -1,33 +0,0 @@
/**
* Provides class representing the `pyramid.redirect` function.
* This module is intended to be imported into a taint-tracking query
* to extend `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
deprecated private ClassValue redirectClass() {
exists(ModuleValue ex | ex.getName() = "pyramid.httpexceptions" |
ex.attr("HTTPFound") = result
or
ex.attr("HTTPTemporaryRedirect") = result
)
}
/**
* Represents an argument to the `tornado.redirect` function.
*/
deprecated class PyramidRedirect extends HttpRedirectTaintSink {
override string toString() { result = "pyramid.redirect" }
PyramidRedirect() {
exists(CallNode call | call.getFunction().pointsTo(redirectClass()) |
call.getArg(0) = this
or
call.getArgByName("location") = this
)
}
}

View File

@@ -1,37 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
private import semmle.python.web.pyramid.View
/**
* A pyramid response, which is vulnerable to any sort of
* http response malice.
*/
deprecated class PyramidRoutedResponse extends HttpResponseTaintSink {
PyramidRoutedResponse() {
exists(PythonFunctionValue view |
is_pyramid_view_function(view.getScope()) and
this = view.getAReturnedNode()
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
override string toString() { result = "pyramid.routed.response" }
}
deprecated class PyramidCookieSet extends CookieSet, CallNode {
PyramidCookieSet() {
exists(ControlFlowNode f |
f = this.getFunction().(AttrNode).getObject("set_cookie") and
f.pointsTo().getClass() = Value::named("pyramid.response.Response")
)
}
override string toString() { result = CallNode.super.toString() }
override ControlFlowNode getKey() { result = this.getArg(0) }
override ControlFlowNode getValue() { result = this.getArg(1) }
}

View File

@@ -1,43 +0,0 @@
/**
* Provides the sinks for HTTP servers defined with standard library (stdlib).
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
deprecated private predicate is_wfile(AttrNode wfile) {
exists(ClassValue cls |
// Python 2
cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler")
or
// Python 3
cls.getABaseType+() = Value::named("http.server.BaseHTTPRequestHandler")
|
wfile.getObject("wfile").pointsTo().getClass() = cls
)
}
/** Sink for `h.wfile.write` where `h` is an instance of BaseHttpRequestHandler. */
deprecated class StdLibWFileWriteSink extends HttpResponseTaintSink {
StdLibWFileWriteSink() {
exists(CallNode call |
is_wfile(call.getFunction().(AttrNode).getObject("write")) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/** Sink for `h.wfile.writelines` where `h` is an instance of BaseHttpRequestHandler. */
deprecated class StdLibWFileWritelinesSink extends HttpResponseTaintSink {
StdLibWFileWritelinesSink() {
exists(CallNode call |
is_wfile(call.getFunction().(AttrNode).getObject("writelines")) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
}

View File

@@ -1,28 +0,0 @@
/**
* Provides class representing the `tornado.redirect` function.
* This module is intended to be imported into a taint-tracking query
* to extend `TaintSink`.
*/
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
import Tornado
/**
* Represents an argument to the `tornado.redirect` function.
*/
deprecated class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink {
override string toString() { result = "tornado.HttpRequestHandler.redirect" }
TornadoHttpRequestHandlerRedirect() {
exists(CallNode call, ControlFlowNode node |
node = call.getFunction().(AttrNode).getObject("redirect") and
isTornadoRequestHandlerInstance(node) and
this = call.getArg(0)
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}

View File

@@ -1,47 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
private import semmle.python.web.Http
import Tornado
deprecated class TornadoConnection extends TaintKind {
TornadoConnection() { this = "tornado.http.connection" }
}
deprecated class TornadoConnectionSource extends TaintSource {
TornadoConnectionSource() {
isTornadoRequestHandlerInstance(this.(AttrNode).getObject("connection"))
}
override string toString() { result = "Tornado http connection source" }
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoConnection }
}
deprecated class TornadoConnectionWrite extends HttpResponseTaintSink {
override string toString() { result = "tornado.connection.write" }
TornadoConnectionWrite() {
exists(CallNode call, ControlFlowNode conn |
conn = call.getFunction().(AttrNode).getObject("write") and
this = call.getAnArg() and
exists(TornadoConnection tc | tc.taints(conn))
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
deprecated class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
override string toString() { result = "tornado.HttpRequestHandler.write" }
TornadoHttpRequestHandlerWrite() {
exists(CallNode call, ControlFlowNode node |
node = call.getFunction().(AttrNode).getObject("write") and
this = call.getAnArg() and
isTornadoRequestHandlerInstance(node)
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}

View File

@@ -1,31 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
import TurboGears
deprecated class ControllerMethodReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodReturnValue" }
ControllerMethodReturnValue() {
exists(TurboGearsControllerMethod m |
m.getAReturnValueFlowNode() = this and
not m.isTemplated()
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
deprecated class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodTemplatedReturnValue" }
ControllerMethodTemplatedReturnValue() {
exists(TurboGearsControllerMethod m |
m.getAReturnValueFlowNode() = this and
m.isTemplated()
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringDictKind }
}

View File

@@ -1,45 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
import semmle.python.security.strings.Basic
import Twisted
import Request
deprecated class TwistedResponse extends HttpResponseTaintSink {
TwistedResponse() {
exists(PythonFunctionValue func, string name |
isKnownRequestHandlerMethodName(name) and
name = func.getName() and
func = getTwistedRequestHandlerMethod(name) and
this = func.getAReturnedNode()
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "Twisted response" }
}
/**
* A sink of taint in the form of a "setter" method on a twisted request
* object, which affects the properties of the subsequent response sent to this
* request.
*/
deprecated class TwistedRequestSetter extends HttpResponseTaintSink {
TwistedRequestSetter() {
exists(CallNode call, ControlFlowNode node, string name |
(
name = "setHeader" or
name = "addCookie" or
name = "write"
) and
any(TwistedRequest t).taints(node) and
node = call.getFunction().(AttrNode).getObject(name) and
this = call.getAnArg()
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "Twisted request setter" }
}

View File

@@ -13,13 +13,10 @@
*/
import python
import semmle.python.security.Paths
import semmle.python.dataflow.TaintTracking
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.filters.Tests
class HardcodedValue extends TaintKind {
HardcodedValue() { this = "hard coded value" }
}
import DataFlow::PathGraph
bindingset[char, fraction]
predicate fewer_characters_than(StrConst str, string char, float fraction) {
@@ -78,31 +75,27 @@ predicate maybeCredential(ControlFlowNode f) {
)
}
class HardcodedValueSource extends TaintSource {
HardcodedValueSource() { maybeCredential(this) }
override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue }
class HardcodedValueSource extends DataFlow::Node {
HardcodedValueSource() { maybeCredential(this.asCfgNode()) }
}
class CredentialSink extends TaintSink {
class CredentialSink extends DataFlow::Node {
CredentialSink() {
exists(string name |
name.regexpMatch(getACredentialRegex()) and
not name.matches("%file")
|
any(FunctionValue func).getNamedArgumentForCall(_, name) = this
any(FunctionValue func).getNamedArgumentForCall(_, name) = this.asCfgNode()
or
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this)
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this.asCfgNode())
or
exists(CompareNode cmp, NameNode n | n.getId() = name |
cmp.operands(this, any(Eq eq), n)
cmp.operands(this.asCfgNode(), any(Eq eq), n)
or
cmp.operands(n, any(Eq eq), this)
cmp.operands(n, any(Eq eq), this.asCfgNode())
)
)
}
override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue }
}
/**
@@ -118,16 +111,14 @@ private string getACredentialRegex() {
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" }
override predicate isSource(TaintTracking::Source source) {
source instanceof HardcodedValueSource
}
override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource }
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink }
}
from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink
from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink
where
config.hasFlowPath(src, sink) and
not any(TestScope test).contains(src.getAstNode())
select src.getSource(), src, sink, "This hardcoded value is $@.", sink.getNode(),
not any(TestScope test).contains(src.getNode().asCfgNode().getNode())
select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(),
"used as credentials"

View File

@@ -1,44 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.Exceptions
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}
class ExceptionInfoSource extends TaintSource {
ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo }
override string toString() { result = "Exception info source" }
}
class ExternalFileObjectSource extends TaintSource {
ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject }
override string toString() { result = "Tainted file source" }
}

View File

@@ -1 +0,0 @@
| test.py:4 | ok | fstring | Fstring | externally controlled string |

View File

@@ -1,33 +0,0 @@
import python
import semmle.python.security.TaintTracking
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
import Taint
from
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
(
call.getFunc().(Name).getId() = "ensure_tainted" and
expected_taint = true
or
call.getFunc().(Name).getId() = "ensure_not_tainted" and
expected_taint = false
) and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "<NO TAINT>" and
has_taint = false
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
) and
has_taint = true
) and
if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,5 +0,0 @@
def fstring():
tainted_string = TAINTED_STRING
ensure_tainted(
f"foo {tainted_string} bar"
)

View File

@@ -1,27 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}

View File

@@ -1,9 +0,0 @@
| test.py:11 | extended_unpacking | first | externally controlled string |
| test.py:11 | extended_unpacking | last | externally controlled string |
| test.py:11 | extended_unpacking | rest | [externally controlled string] |
| test.py:16 | also_allowed | a | [externally controlled string] |
| test.py:24 | also_allowed | b | NO TAINT |
| test.py:24 | also_allowed | c | NO TAINT |
| test.py:31 | nested | x | externally controlled string |
| test.py:31 | nested | xs | [externally controlled string] |
| test.py:31 | nested | ys | [externally controlled string] |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,31 +0,0 @@
# Extended Iterable Unpacking -- PEP 3132
# https://www.python.org/dev/peps/pep-3132/
def test(*args):
pass
def extended_unpacking():
first, *rest, last = TAINTED_LIST
test(first, rest, last)
def also_allowed():
*a, = TAINTED_LIST
test(a)
# for b, *c in [(1, 2, 3), (4, 5, 6, 7)]:
# print(c)
# i=0; c=[2,3]
# i=1; c=[5,6,7]
for b, *c in [TAINTED_LIST, TAINTED_LIST]:
test(b, c) # TODO: mark `c` as [taint]
def nested():
l = TAINTED_LIST
ll = [l,l]
[[x, *xs], ys] = ll
test(x, xs, ys)

View File

@@ -1,23 +0,0 @@
| MySanitizerHandlingNot | externally controlled string | test.py:13 | Pi(s_0) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:18 | Pi(s_5) [false] |
| MySanitizerHandlingNot | externally controlled string | test.py:28 | Pi(s_0) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:34 | Pi(s_10) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:40 | Pi(s_12) [false] |
| MySanitizerHandlingNot | externally controlled string | test.py:50 | Pi(s_0) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:56 | Pi(s_10) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:62 | Pi(s_12) [false] |
| MySanitizerHandlingNot | externally controlled string | test.py:76 | Pi(s_3) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:82 | Pi(s_0) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:87 | Pi(s_5) [false] |
| MySanitizerHandlingNot | externally controlled string | test.py:97 | Pi(s_0) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:102 | Pi(s_7) [true] |
| MySanitizerHandlingNot | externally controlled string | test.py:107 | Pi(s_12) [true] |
| MySimpleSanitizer | externally controlled string | test.py:13 | Pi(s_0) [true] |
| MySimpleSanitizer | externally controlled string | test.py:28 | Pi(s_0) [true] |
| MySimpleSanitizer | externally controlled string | test.py:34 | Pi(s_10) [true] |
| MySimpleSanitizer | externally controlled string | test.py:50 | Pi(s_0) [true] |
| MySimpleSanitizer | externally controlled string | test.py:56 | Pi(s_10) [true] |
| MySimpleSanitizer | externally controlled string | test.py:76 | Pi(s_3) [true] |
| MySimpleSanitizer | externally controlled string | test.py:97 | Pi(s_0) [true] |
| MySimpleSanitizer | externally controlled string | test.py:102 | Pi(s_7) [true] |
| MySimpleSanitizer | externally controlled string | test.py:107 | Pi(s_12) [true] |

View File

@@ -1,6 +0,0 @@
import python
import Taint
from Sanitizer s, TaintKind taint, PyEdgeRefinement test
where s.sanitizingEdge(taint, test)
select s, taint, test.getTest().getLocation().toString(), test.getRepresentation()

View File

@@ -1,77 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class MySimpleSanitizer extends Sanitizer {
MySimpleSanitizer() { this = "MySimpleSanitizer" }
/*
* The test `if is_safe(arg):` sanitizes `arg` on its `true` edge.
*
* Can't handle `if not is_safe(arg):` :\ that's why it's called MySimpleSanitizer
*/
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
taint instanceof ExternalStringKind and
exists(CallNode call | test.getTest() = call and test.getSense() = true |
call = Value::named("test.is_safe").getACall() and
test.getInput().getAUse() = call.getAnArg()
)
}
}
class MySanitizerHandlingNot extends Sanitizer {
MySanitizerHandlingNot() { this = "MySanitizerHandlingNot" }
/** Holds if the test `if is_safe(arg):` sanitizes `arg` on its `true` edge. */
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
taint instanceof ExternalStringKind and
clears_taint_on_true(test.getTest(), test.getSense(), test)
}
}
/**
* Helper predicate that recurses into any nesting of `not`
*
* To reduce the number of tuples this predicate holds for, we include the `PyEdgeRefinement` and
* ensure that `test` is a part of this `PyEdgeRefinement` (instead of just taking the
* `edge_refinement.getInput().getAUse()` part as a part of the predicate). Without including
* `PyEdgeRefinement` as an argument *any* `CallNode c` to `test.is_safe` would be a result of
* this predicate, since the tuple where `test = c` and `sense = true` would hold.
*/
private predicate clears_taint_on_true(
ControlFlowNode test, boolean sense, PyEdgeRefinement edge_refinement
) {
edge_refinement.getTest().getNode().(Expr).getASubExpression*() = test.getNode() and
(
test = Value::named("test.is_safe").getACall() and
edge_refinement.getInput().getAUse() = test.(CallNode).getAnArg() and
sense = true
or
test.(UnaryExprNode).getNode().getOp() instanceof Not and
exists(ControlFlowNode nested_test |
nested_test = test.(UnaryExprNode).getOperand() and
clears_taint_on_true(nested_test, sense.booleanNot(), edge_refinement)
)
)
}
class TestConfig extends TaintTracking::Configuration {
TestConfig() { this = "TestConfig" }
override predicate isSanitizer(Sanitizer sanitizer) {
sanitizer instanceof MySanitizerHandlingNot
}
override predicate isSource(TaintTracking::Source source) { source instanceof SimpleSource }
override predicate isSink(TaintTracking::Sink sink) { none() }
}

View File

@@ -1,28 +0,0 @@
| test.py:14 | test_basic | s | <NO TAINT> | ok |
| test.py:16 | test_basic | s | externally controlled string | ok |
| test.py:19 | test_basic | s | externally controlled string | ok |
| test.py:21 | test_basic | s | <NO TAINT> | ok |
| test.py:29 | test_or | s | externally controlled string | ok |
| test.py:31 | test_or | s | externally controlled string | ok |
| test.py:35 | test_or | s | externally controlled string | ok |
| test.py:37 | test_or | s | externally controlled string | ok |
| test.py:41 | test_or | s | externally controlled string | ok |
| test.py:43 | test_or | s | externally controlled string | ok |
| test.py:51 | test_and | s | <NO TAINT> | ok |
| test.py:53 | test_and | s | externally controlled string | ok |
| test.py:57 | test_and | s | externally controlled string | ok |
| test.py:59 | test_and | s | <NO TAINT> | ok |
| test.py:63 | test_and | s | externally controlled string | ok |
| test.py:65 | test_and | s | <NO TAINT> | ok |
| test.py:73 | test_tricky | s | externally controlled string | failure |
| test.py:77 | test_tricky | s_ | externally controlled string | failure |
| test.py:83 | test_nesting_not | s | <NO TAINT> | ok |
| test.py:85 | test_nesting_not | s | externally controlled string | ok |
| test.py:88 | test_nesting_not | s | externally controlled string | ok |
| test.py:90 | test_nesting_not | s | <NO TAINT> | ok |
| test.py:98 | test_nesting_not_with_and_true | s | externally controlled string | ok |
| test.py:100 | test_nesting_not_with_and_true | s | <NO TAINT> | ok |
| test.py:103 | test_nesting_not_with_and_true | s | <NO TAINT> | ok |
| test.py:105 | test_nesting_not_with_and_true | s | externally controlled string | ok |
| test.py:108 | test_nesting_not_with_and_true | s | externally controlled string | ok |
| test.py:110 | test_nesting_not_with_and_true | s | <NO TAINT> | ok |

View File

@@ -1,31 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
(
call.getFunc().(Name).getId() = "ensure_tainted" and
expected_taint = true
or
call.getFunc().(Name).getId() = "ensure_not_tainted" and
expected_taint = false
) and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "<NO TAINT>" and
has_taint = false
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
) and
has_taint = true
) and
if expected_taint = has_taint then test_res = "ok" else test_res = "failure"
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string, test_res

View File

@@ -1,110 +0,0 @@
def random_choice():
return bool(GLOBAL_UNKOWN_VAR)
def is_safe(arg):
return UNKNOWN_FUNC(arg)
def true_func():
return True
def test_basic():
s = TAINTED_STRING
if is_safe(s):
ensure_not_tainted(s)
else:
ensure_tainted(s)
if not is_safe(s):
ensure_tainted(s)
else:
ensure_not_tainted(s)
def test_or():
s = TAINTED_STRING
# x or y
if is_safe(s) or random_choice():
ensure_tainted(s) # might be tainted
else:
ensure_tainted(s) # must be tainted
# not (x or y)
if not(is_safe(s) or random_choice()):
ensure_tainted(s) # must be tainted
else:
ensure_tainted(s) # might be tainted
# not (x or y) == not x and not y [de Morgan's laws]
if not is_safe(s) and not random_choice():
ensure_tainted(s) # must be tainted
else:
ensure_tainted(s) # might be tainted
def test_and():
s = TAINTED_STRING
# x and y
if is_safe(s) and random_choice():
ensure_not_tainted(s) # must not be tainted
else:
ensure_tainted(s) # might be tainted
# not (x and y)
if not(is_safe(s) and random_choice()):
ensure_tainted(s) # might be tainted
else:
ensure_not_tainted(s)
# not (x and y) == not x or not y [de Morgan's laws]
if not is_safe(s) or not random_choice():
ensure_tainted(s) # might be tainted
else:
ensure_not_tainted(s)
def test_tricky():
s = TAINTED_STRING
x = is_safe(s)
if x:
ensure_not_tainted(s) # FP
s_ = s
if is_safe(s):
ensure_not_tainted(s_) # FP
def test_nesting_not():
s = TAINTED_STRING
if not(not(is_safe(s))):
ensure_not_tainted(s)
else:
ensure_tainted(s)
if not(not(not(is_safe(s)))):
ensure_tainted(s)
else:
ensure_not_tainted(s)
# Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in
# SanitizedEdges.expected and compare with `test_nesting_not` and `test_basic`
def test_nesting_not_with_and_true():
s = TAINTED_STRING
if not(is_safe(s) and True):
ensure_tainted(s)
else:
ensure_not_tainted(s)
if not(not(is_safe(s) and True)):
ensure_not_tainted(s)
else:
ensure_tainted(s)
if not(not(not(is_safe(s) and True))):
ensure_tainted(s)
else:
ensure_not_tainted(s)

View File

@@ -1,18 +0,0 @@
WARNING: Type CommandSink has been deprecated and may be removed in future (CommandSinks.ql:4,6-17)
| fabric_v1_test.py:8:7:8:28 | FabricV1Commands | externally controlled string |
| fabric_v1_test.py:9:5:9:27 | FabricV1Commands | externally controlled string |
| fabric_v1_test.py:10:6:10:38 | FabricV1Commands | externally controlled string |
| fabric_v2_test.py:10:16:10:25 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:12:15:12:36 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:16:45:16:54 | FabricGroupRun | externally controlled string |
| fabric_v2_test.py:21:10:21:13 | FabricGroupRun | externally controlled string |
| fabric_v2_test.py:31:14:31:41 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:33:15:33:64 | InvokeContextRun | externally controlled string |
| invoke_test.py:8:12:8:21 | InvokeRun | externally controlled string |
| invoke_test.py:9:20:9:40 | InvokeRun | externally controlled string |
| invoke_test.py:12:17:12:24 | InvokeRun | externally controlled string |
| invoke_test.py:13:25:13:32 | InvokeRun | externally controlled string |
| invoke_test.py:17:11:17:40 | InvokeContextRun | externally controlled string |
| invoke_test.py:21:11:21:32 | InvokeContextRun | externally controlled string |
| invoke_test.py:27:11:27:25 | InvokeContextRun | externally controlled string |
| invoke_test.py:32:11:32:25 | InvokeContextRun | externally controlled string |

View File

@@ -1,6 +0,0 @@
import python
import semmle.python.security.injection.Command
from CommandSink sink, TaintKind kind
where sink.sinks(kind)
select sink, kind

View File

@@ -1,22 +0,0 @@
Copyright (c) 2020 Jeff Forcier.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,10 +0,0 @@
"""tests for the 'fabric' package (v1.x)
See http://docs.fabfile.org/en/1.14/tutorial.html
"""
from fabric.api import run, local, sudo
local('echo local execution')
run('echo remote execution')
sudo('echo remote execution with sudo')

View File

@@ -1,33 +0,0 @@
"""tests for the 'fabric' package (v2.x)
Most of these examples are taken from the fabric documentation: http://docs.fabfile.org/en/2.5/getting-started.html
See fabric-LICENSE for its' license.
"""
from fabric import Connection
c = Connection('web1')
result = c.run('uname -s')
c.run(command='echo run with kwargs')
from fabric import SerialGroup as Group
results = Group('web1', 'web2', 'mac1').run('uname -s')
from fabric import SerialGroup as Group
pool = Group('web1', 'web2', 'web3')
pool.run('ls')
# using the 'fab' command-line tool
from fabric import task
@task
def upload_and_unpack(c):
if c.run('test -f /opt/mydata/myfile', warn=True).failed:
c.put('myfiles.tgz', '/opt/mydata')
c.run('tar -C /opt/mydata -xzvf /opt/mydata/myfiles.tgz')

View File

@@ -1,32 +0,0 @@
"""tests for the 'invoke' package
see https://www.pyinvoke.org/
"""
import invoke
invoke.run('echo run')
invoke.run(command='echo run with kwarg')
def with_sudo():
invoke.sudo('whoami')
invoke.sudo(command='whoami')
def manual_context():
c = invoke.Context()
c.run('echo run from manual context')
manual_context()
def foo_helper(c):
c.run('echo from foo_helper')
# for use with the 'invoke' command-line tool
@invoke.task
def foo(c):
# 'c' is a invoke.context.Context
c.run('echo task foo')
foo_helper(c)
@invoke.task()
def bar(c):
c.run('echo task bar')

View File

@@ -1 +0,0 @@
semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/

View File

@@ -1,24 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.injection.Command
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class FabricExecuteTestConfiguration extends TaintTracking::Configuration {
FabricExecuteTestConfiguration() { this = "FabricExecuteTestConfiguration" }
override predicate isSource(TaintTracking::Source source) { source instanceof SimpleSource }
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CommandSink }
override predicate isExtension(TaintTracking::Extension extension) {
extension instanceof FabricExecuteExtension
}
}

View File

@@ -1,10 +0,0 @@
| test.py:8 | ok | unsafe | cmd | externally controlled string |
| test.py:8 | ok | unsafe | cmd2 | externally controlled string |
| test.py:9 | ok | unsafe | safe_arg | <NO TAINT> |
| test.py:9 | ok | unsafe | safe_optional | <NO TAINT> |
| test.py:16 | ok | unsafe | cmd | externally controlled string |
| test.py:16 | ok | unsafe | cmd2 | externally controlled string |
| test.py:17 | ok | unsafe | safe_arg | <NO TAINT> |
| test.py:17 | ok | unsafe | safe_optional | <NO TAINT> |
| test.py:23 | ok | some_http_handler | cmd | externally controlled string |
| test.py:23 | ok | some_http_handler | cmd2 | externally controlled string |

View File

@@ -1,33 +0,0 @@
import python
import semmle.python.security.TaintTracking
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
import Taint
from
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
(
call.getFunc().(Name).getId() = "ensure_tainted" and
expected_taint = true
or
call.getFunc().(Name).getId() = "ensure_not_tainted" and
expected_taint = false
) and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "<NO TAINT>" and
has_taint = false
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
) and
has_taint = true
) and
if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1 +0,0 @@
semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/

View File

@@ -1,28 +0,0 @@
"""Test that shows fabric.api.execute propagates taint"""
from fabric.api import run, execute
def unsafe(cmd, safe_arg, cmd2=None, safe_optional=5):
run('./venv/bin/activate && {}'.format(cmd))
ensure_tainted(cmd, cmd2)
ensure_not_tainted(safe_arg, safe_optional)
class Foo(object):
def unsafe(self, cmd, safe_arg, cmd2=None, safe_optional=5):
run('./venv/bin/activate && {}'.format(cmd))
ensure_tainted(cmd, cmd2)
ensure_not_tainted(safe_arg, safe_optional)
def some_http_handler():
cmd = TAINTED_STRING
cmd2 = TAINTED_STRING
ensure_tainted(cmd, cmd2)
execute(unsafe, cmd=cmd, safe_arg='safe_arg', cmd2=cmd2)
foo = Foo()
execute(foo.unsafe, cmd, 'safe_arg', cmd2)

View File

@@ -1,27 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}

View File

@@ -1,63 +0,0 @@
| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:14 | test.py:14:14:14:25 | tainted_list | |
| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:20 | test.py:20:15:20:26 | tainted_list | |
| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:21 | test.py:21:13:21:24 | tainted_list | |
| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:22 | test.py:22:19:22:30 | tainted_list | |
| Taint [externally controlled string] | test.py:10 | test.py:10:22:10:36 | Tuple | | --> | Taint [externally controlled string] | test.py:15 | test.py:15:14:15:26 | tainted_tuple | |
| Taint [externally controlled string] | test.py:14 | test.py:14:9:14:26 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:10:23:10 | a | |
| Taint [externally controlled string] | test.py:14 | test.py:14:14:14:25 | tainted_list | | --> | Taint [externally controlled string] | test.py:14 | test.py:14:9:14:26 | list() | |
| Taint [externally controlled string] | test.py:15 | test.py:15:9:15:27 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:13:23:13 | b | |
| Taint [externally controlled string] | test.py:15 | test.py:15:14:15:26 | tainted_tuple | | --> | Taint [externally controlled string] | test.py:15 | test.py:15:9:15:27 | list() | |
| Taint [externally controlled string] | test.py:17 | test.py:17:9:17:35 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:19:23:19 | d | |
| Taint [externally controlled string] | test.py:17 | test.py:17:14:17:34 | Attribute() | | --> | Taint [externally controlled string] | test.py:17 | test.py:17:9:17:35 | list() | |
| Taint [externally controlled string] | test.py:20 | test.py:20:9:20:27 | tuple() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:25:23:25 | f | |
| Taint [externally controlled string] | test.py:20 | test.py:20:15:20:26 | tainted_list | | --> | Taint [externally controlled string] | test.py:20 | test.py:20:9:20:27 | tuple() | |
| Taint [externally controlled string] | test.py:21 | test.py:21:9:21:25 | set() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:28:23:28 | g | |
| Taint [externally controlled string] | test.py:21 | test.py:21:13:21:24 | tainted_list | | --> | Taint [externally controlled string] | test.py:21 | test.py:21:9:21:25 | set() | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:9:27:20 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:28 | test.py:28:9:28:20 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:29 | test.py:29:9:29:20 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:30 | test.py:30:9:30:20 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:33 | test.py:33:14:33:25 | tainted_list | |
| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:35 | test.py:35:23:35:34 | tainted_list | |
| Taint [externally controlled string] | test.py:27 | test.py:27:9:27:20 | tainted_list | | --> | Taint externally controlled string | test.py:27 | test.py:27:9:27:23 | Subscript | |
| Taint [externally controlled string] | test.py:28 | test.py:28:9:28:20 | tainted_list | | --> | Taint externally controlled string | test.py:28 | test.py:28:9:28:23 | Subscript | |
| Taint [externally controlled string] | test.py:29 | test.py:29:9:29:20 | tainted_list | | --> | Taint [externally controlled string] | test.py:29 | test.py:29:9:29:25 | Subscript | |
| Taint [externally controlled string] | test.py:29 | test.py:29:9:29:25 | Subscript | | --> | Taint [externally controlled string] | test.py:32 | test.py:32:16:32:16 | c | |
| Taint [externally controlled string] | test.py:30 | test.py:30:9:30:20 | tainted_list | | --> | Taint [externally controlled string] | test.py:30 | test.py:30:9:30:27 | Attribute() | |
| Taint [externally controlled string] | test.py:30 | test.py:30:9:30:27 | Attribute() | | --> | Taint [externally controlled string] | test.py:32 | test.py:32:19:32:19 | d | |
| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:22:32:22 | e | |
| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:25:32:25 | f | |
| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:28:32:28 | g | |
| Taint [externally controlled string] | test.py:33 | test.py:33:14:33:25 | tainted_list | | --> | Taint externally controlled string | test.py:33 | test.py:33:5:33:26 | For | |
| Taint [externally controlled string] | test.py:35 | test.py:35:14:35:35 | reversed() | | --> | Taint externally controlled string | test.py:35 | test.py:35:5:35:36 | For | |
| Taint [externally controlled string] | test.py:35 | test.py:35:23:35:34 | tainted_list | | --> | Taint [externally controlled string] | test.py:35 | test.py:35:14:35:35 | reversed() | |
| Taint [externally controlled string] | test.py:44 | test.py:44:14:44:34 | Attribute() | | --> | Taint externally controlled string | test.py:44 | test.py:44:5:44:35 | For | |
| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:9 | test.py:9:21:9:34 | tainted_string | |
| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:10 | test.py:10:22:10:35 | tainted_string | |
| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:11 | test.py:11:20:11:33 | tainted_string | |
| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:12 | test.py:12:28:12:41 | tainted_string | |
| Taint externally controlled string | test.py:9 | test.py:9:21:9:34 | tainted_string | | --> | Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | |
| Taint externally controlled string | test.py:10 | test.py:10:22:10:35 | tainted_string | | --> | Taint [externally controlled string] | test.py:10 | test.py:10:22:10:36 | Tuple | |
| Taint externally controlled string | test.py:12 | test.py:12:28:12:41 | tainted_string | | --> | Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | |
| Taint externally controlled string | test.py:27 | test.py:27:9:27:23 | Subscript | | --> | Taint externally controlled string | test.py:32 | test.py:32:10:32:10 | a | |
| Taint externally controlled string | test.py:28 | test.py:28:9:28:23 | Subscript | | --> | Taint externally controlled string | test.py:32 | test.py:32:13:32:13 | b | |
| Taint externally controlled string | test.py:33 | test.py:33:5:33:26 | For | | --> | Taint externally controlled string | test.py:34 | test.py:34:14:34:14 | h | |
| Taint externally controlled string | test.py:35 | test.py:35:5:35:36 | For | | --> | Taint externally controlled string | test.py:36 | test.py:36:14:36:14 | i | |
| Taint externally controlled string | test.py:40 | test.py:40:9:40:28 | Subscript | | --> | Taint externally controlled string | test.py:43 | test.py:43:10:43:10 | a | |
| Taint externally controlled string | test.py:41 | test.py:41:9:41:23 | Subscript | | --> | Taint externally controlled string | test.py:43 | test.py:43:13:43:13 | b | |
| Taint externally controlled string | test.py:44 | test.py:44:5:44:35 | For | | --> | Taint externally controlled string | test.py:45 | test.py:45:14:45:14 | d | |
| Taint externally controlled string | test.py:62 | test.py:62:34:62:47 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:62 | test.py:62:5:62:47 | BinaryExpr | |
| Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | | --> | Taint {externally controlled string} | test.py:17 | test.py:17:14:17:25 | tainted_dict | |
| Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | | --> | Taint {externally controlled string} | test.py:18 | test.py:18:14:18:25 | tainted_dict | |
| Taint {externally controlled string} | test.py:17 | test.py:17:14:17:25 | tainted_dict | | --> | Taint [externally controlled string] | test.py:17 | test.py:17:14:17:34 | Attribute() | |
| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:40 | test.py:40:9:40:20 | tainted_dict | |
| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:41 | test.py:41:9:41:20 | tainted_dict | |
| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:42 | test.py:42:9:42:20 | tainted_dict | |
| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:44 | test.py:44:14:44:25 | tainted_dict | |
| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:46 | test.py:46:17:46:28 | tainted_dict | |
| Taint {externally controlled string} | test.py:40 | test.py:40:9:40:20 | tainted_dict | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:28 | Subscript | |
| Taint {externally controlled string} | test.py:41 | test.py:41:9:41:20 | tainted_dict | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:23 | Subscript | |
| Taint {externally controlled string} | test.py:42 | test.py:42:9:42:20 | tainted_dict | | --> | Taint {externally controlled string} | test.py:42 | test.py:42:9:42:27 | Attribute() | |
| Taint {externally controlled string} | test.py:42 | test.py:42:9:42:27 | Attribute() | | --> | Taint {externally controlled string} | test.py:43 | test.py:43:16:43:16 | c | |
| Taint {externally controlled string} | test.py:44 | test.py:44:14:44:25 | tainted_dict | | --> | Taint [externally controlled string] | test.py:44 | test.py:44:14:44:34 | Attribute() | |

View File

@@ -1,11 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from TaintedNode n, TaintedNode s
where
n.getLocation().getFile().getShortName() = "test.py" and
s.getLocation().getFile().getShortName() = "test.py" and
s = n.getASuccessor()
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(),
" --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext()

View File

@@ -1,33 +0,0 @@
| test.py:23 | test_construction | a | [externally controlled string] |
| test.py:23 | test_construction | b | [externally controlled string] |
| test.py:23 | test_construction | c | NO TAINT |
| test.py:23 | test_construction | d | [externally controlled string] |
| test.py:23 | test_construction | e | NO TAINT |
| test.py:23 | test_construction | f | [externally controlled string] |
| test.py:23 | test_construction | g | [externally controlled string] |
| test.py:23 | test_construction | h | NO TAINT |
| test.py:32 | test_access | a | externally controlled string |
| test.py:32 | test_access | b | externally controlled string |
| test.py:32 | test_access | c | [externally controlled string] |
| test.py:32 | test_access | d | [externally controlled string] |
| test.py:32 | test_access | e | externally controlled string |
| test.py:32 | test_access | f | externally controlled string |
| test.py:32 | test_access | g | externally controlled string |
| test.py:34 | test_access | h | externally controlled string |
| test.py:36 | test_access | i | externally controlled string |
| test.py:43 | test_dict_access | a | externally controlled string |
| test.py:43 | test_dict_access | b | externally controlled string |
| test.py:43 | test_dict_access | c | {externally controlled string} |
| test.py:45 | test_dict_access | d | externally controlled string |
| test.py:47 | test_dict_access | e | NO TAINT |
| test.py:58 | test_named_tuple | a | NO TAINT |
| test.py:58 | test_named_tuple | b | NO TAINT |
| test.py:58 | test_named_tuple | c | NO TAINT |
| test.py:58 | test_named_tuple | d | NO TAINT |
| test.py:58 | test_named_tuple | e | NO TAINT |
| test.py:58 | test_named_tuple | f | NO TAINT |
| test.py:67 | test_defaultdict | a | NO TAINT |
| test.py:67 | test_defaultdict | b | NO TAINT |
| test.py:67 | test_defaultdict | c | NO TAINT |
| test.py:69 | test_defaultdict | d | NO TAINT |
| test.py:71 | test_defaultdict | e | NO TAINT |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,71 +0,0 @@
from collections import defaultdict, namedtuple
# Use to show only interesting results in qltest output
def test(*args):
pass
def test_construction():
tainted_string = TAINTED_STRING
tainted_list = [tainted_string]
tainted_tuple = (tainted_string,)
tainted_set = {tainted_string} # TODO: set currently not handled
tainted_dict = {'key': tainted_string}
a = list(tainted_list)
b = list(tainted_tuple)
c = list(tainted_set) # TODO: set currently not handled
d = list(tainted_dict.values())
e = list(tainted_dict.items()) # TODO: dict.items() currently not handled
f = tuple(tainted_list)
g = set(tainted_list)
h = frozenset(tainted_list) # TODO: frozenset constructor currently not handled
test(a, b, c, d, e, f, g, h)
def test_access():
tainted_list = TAINTED_LIST
a = tainted_list[0]
b = tainted_list[x]
c = tainted_list[y:z]
d = tainted_list.copy()
e, f, g = tainted_list
test(a, b, c, d, e, f, g)
for h in tainted_list:
test(h)
for i in reversed(tainted_list):
test(i)
def test_dict_access(x):
tainted_dict = TAINTED_DICT
a = tainted_dict["name"]
b = tainted_dict[x]
c = tainted_dict.copy()
test(a, b, c)
for d in tainted_dict.values():
test(d)
for _, e in tainted_dict.items(): # TODO: dict.items() currently not handled
test(e)
def test_named_tuple(): # TODO: namedtuple currently not handled
Point = namedtuple('Point', ['x', 'y'])
point = Point(TAINTED_STRING, 'const')
a = point[0]
b = point.x
c = point[1]
d = point.y
e, f = point
test(a, b, c, d, e, f)
def test_defaultdict(key, x): # TODO: defaultdict currently not handled
tainted_default_dict = defaultdict(str)
tainted_default_dict[key] += TAINTED_STRING
a = tainted_dict["name"]
b = tainted_dict[x]
c = tainted_dict.copy()
test(a, b, c)
for d in tainted_dict.values():
test(d)
for _, e in tainted_dict.items():
test(e)

View File

@@ -1,99 +1,3 @@
edges
| carrier.py:17:9:17:31 | .attr = simple.test | carrier.py:18:10:18:10 | .attr = simple.test |
| carrier.py:17:25:17:30 | simple.test | carrier.py:17:9:17:31 | .attr = simple.test |
| carrier.py:18:10:18:10 | .attr = simple.test | carrier.py:18:10:18:15 | simple.test |
| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier |
| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test |
| carrier.py:25:9:25:36 | .attr = simple.test | carrier.py:26:10:26:10 | .attr = simple.test |
| carrier.py:25:13:25:35 | .attr = simple.test | carrier.py:25:9:25:36 | .attr = simple.test |
| carrier.py:25:29:25:34 | simple.test | carrier.py:25:13:25:35 | .attr = simple.test |
| carrier.py:26:10:26:10 | .attr = simple.test | carrier.py:26:10:26:21 | simple.test |
| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier |
| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier |
| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test |
| carrier.py:33:9:33:45 | .attr = explicit.carrier | carrier.py:34:9:34:9 | .attr = explicit.carrier |
| carrier.py:33:25:33:44 | explicit.carrier | carrier.py:33:9:33:45 | .attr = explicit.carrier |
| carrier.py:34:9:34:9 | .attr = explicit.carrier | carrier.py:34:9:34:14 | explicit.carrier |
| carrier.py:34:9:34:14 | explicit.carrier | carrier.py:35:10:35:10 | explicit.carrier |
| carrier.py:35:10:35:10 | explicit.carrier | carrier.py:35:10:35:22 | simple.test |
| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test |
| deep.py:20:8:20:13 | simple.test | deep.py:20:5:20:14 | simple.test |
| module.py:3:13:3:18 | simple.test | test.py:85:8:85:13 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:88:9:88:14 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:110:11:110:16 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:115:11:115:16 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:155:20:155:38 | simple.test |
| module.py:7:12:7:17 | simple.test | test.py:100:9:100:31 | simple.test |
| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock |
| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors |
| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper |
| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper |
| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection |
| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection |
| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection |
| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection |
| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection |
| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection |
| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:44:12:44:22 | simple.test |
| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test |
| test.py:16:9:16:16 | simple.test | test.py:17:10:17:10 | simple.test |
| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test |
| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:24:9:24:16 | simple.test | test.py:25:10:25:10 | simple.test |
| test.py:25:10:25:10 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test |
| test.py:44:12:44:22 | simple.test | test.py:54:9:54:17 | simple.test |
| test.py:46:11:46:13 | simple.test | test.py:47:10:47:12 | simple.test |
| test.py:47:10:47:12 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test |
| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:54:9:54:17 | simple.test | test.py:55:11:55:11 | simple.test |
| test.py:55:11:55:11 | simple.test | test.py:46:11:46:13 | simple.test |
| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test |
| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test |
| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test |
| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test |
| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test |
| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test |
| test.py:77:13:77:13 | simple.test | test.py:77:9:77:14 | simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:88:9:88:14 | .dangerous = simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:110:11:110:16 | .dangerous = simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:115:11:115:16 | .dangerous = simple.test |
| test.py:88:9:88:14 | .dangerous = simple.test | test.py:88:9:88:24 | simple.test |
| test.py:88:9:88:24 | simple.test | test.py:89:10:89:10 | simple.test |
| test.py:100:9:100:31 | simple.test | test.py:101:10:101:10 | simple.test |
| test.py:105:12:105:14 | .x = simple.test | test.py:106:10:106:12 | .x = simple.test |
| test.py:106:10:106:12 | .x = simple.test | test.py:106:10:106:14 | simple.test |
| test.py:110:11:110:16 | .dangerous = simple.test | test.py:110:11:110:26 | simple.test |
| test.py:110:11:110:26 | simple.test | test.py:111:10:111:10 | .x = simple.test |
| test.py:111:10:111:10 | .x = simple.test | test.py:111:10:111:12 | simple.test |
| test.py:115:11:115:16 | .dangerous = simple.test | test.py:115:11:115:26 | simple.test |
| test.py:115:11:115:26 | simple.test | test.py:116:13:116:13 | .x = simple.test |
| test.py:116:9:116:14 | .x = simple.test | test.py:117:12:117:12 | .x = simple.test |
| test.py:116:13:116:13 | .x = simple.test | test.py:116:9:116:14 | .x = simple.test |
| test.py:117:12:117:12 | .x = simple.test | test.py:105:12:105:14 | .x = simple.test |
| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test |
| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test |
| test.py:155:20:155:38 | simple.test | test.py:156:6:156:11 | simple.test |
| test.py:159:10:159:15 | simple.test | test.py:160:14:160:14 | simple.test |
| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test |
| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test |
| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test |
| test.py:195:9:195:14 | simple.test | test.py:197:14:197:14 | simple.test |
| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test |
| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test |
| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test |
| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test |
| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test |
| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple |
| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test |
| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test |
| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test |
| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test |
#select
| rockpaperscissors.py:13:10:13:17 | SCISSORS | rockpaperscissors.py:13:10:13:17 | scissors | rockpaperscissors.py:13:10:13:17 | scissors | $@ loses to $@. | rockpaperscissors.py:13:10:13:17 | SCISSORS | scissors | rockpaperscissors.py:13:10:13:17 | SCISSORS | scissors |
| rockpaperscissors.py:16:11:16:14 | ROCK | rockpaperscissors.py:16:11:16:14 | rock | rockpaperscissors.py:16:11:16:14 | rock | $@ loses to $@. | rockpaperscissors.py:16:11:16:14 | ROCK | rock | rockpaperscissors.py:16:11:16:14 | ROCK | rock |
| rockpaperscissors.py:26:14:26:14 | y | rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:26:14:26:14 | paper | $@ loses to $@. | rockpaperscissors.py:24:9:24:12 | ROCK | rock | rockpaperscissors.py:26:14:26:14 | y | paper |

View File

@@ -5,7 +5,6 @@
import python
import semmle.python.dataflow.TaintTracking
import TaintLib
import semmle.python.security.Paths
from RockPaperScissorConfig config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)

View File

@@ -1,99 +1,3 @@
edges
| carrier.py:17:9:17:31 | .attr = simple.test | carrier.py:18:10:18:10 | .attr = simple.test |
| carrier.py:17:25:17:30 | simple.test | carrier.py:17:9:17:31 | .attr = simple.test |
| carrier.py:18:10:18:10 | .attr = simple.test | carrier.py:18:10:18:15 | simple.test |
| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier |
| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test |
| carrier.py:25:9:25:36 | .attr = simple.test | carrier.py:26:10:26:10 | .attr = simple.test |
| carrier.py:25:13:25:35 | .attr = simple.test | carrier.py:25:9:25:36 | .attr = simple.test |
| carrier.py:25:29:25:34 | simple.test | carrier.py:25:13:25:35 | .attr = simple.test |
| carrier.py:26:10:26:10 | .attr = simple.test | carrier.py:26:10:26:21 | simple.test |
| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier |
| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier |
| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test |
| carrier.py:33:9:33:45 | .attr = explicit.carrier | carrier.py:34:9:34:9 | .attr = explicit.carrier |
| carrier.py:33:25:33:44 | explicit.carrier | carrier.py:33:9:33:45 | .attr = explicit.carrier |
| carrier.py:34:9:34:9 | .attr = explicit.carrier | carrier.py:34:9:34:14 | explicit.carrier |
| carrier.py:34:9:34:14 | explicit.carrier | carrier.py:35:10:35:10 | explicit.carrier |
| carrier.py:35:10:35:10 | explicit.carrier | carrier.py:35:10:35:22 | simple.test |
| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test |
| deep.py:20:8:20:13 | simple.test | deep.py:20:5:20:14 | simple.test |
| module.py:3:13:3:18 | simple.test | test.py:85:8:85:13 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:88:9:88:14 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:110:11:110:16 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:115:11:115:16 | .dangerous = simple.test |
| module.py:3:13:3:18 | simple.test | test.py:155:20:155:38 | simple.test |
| module.py:7:12:7:17 | simple.test | test.py:100:9:100:31 | simple.test |
| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock |
| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors |
| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper |
| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper |
| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection |
| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection |
| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection |
| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection |
| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection |
| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection |
| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test |
| test.py:10:12:10:17 | simple.test | test.py:44:12:44:22 | simple.test |
| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test |
| test.py:16:9:16:16 | simple.test | test.py:17:10:17:10 | simple.test |
| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test |
| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:24:9:24:16 | simple.test | test.py:25:10:25:10 | simple.test |
| test.py:25:10:25:10 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test |
| test.py:44:12:44:22 | simple.test | test.py:54:9:54:17 | simple.test |
| test.py:46:11:46:13 | simple.test | test.py:47:10:47:12 | simple.test |
| test.py:47:10:47:12 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test |
| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test |
| test.py:54:9:54:17 | simple.test | test.py:55:11:55:11 | simple.test |
| test.py:55:11:55:11 | simple.test | test.py:46:11:46:13 | simple.test |
| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test |
| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test |
| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test |
| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test |
| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test |
| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test |
| test.py:77:13:77:13 | simple.test | test.py:77:9:77:14 | simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:88:9:88:14 | .dangerous = simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:110:11:110:16 | .dangerous = simple.test |
| test.py:85:8:85:13 | .dangerous = simple.test | test.py:115:11:115:16 | .dangerous = simple.test |
| test.py:88:9:88:14 | .dangerous = simple.test | test.py:88:9:88:24 | simple.test |
| test.py:88:9:88:24 | simple.test | test.py:89:10:89:10 | simple.test |
| test.py:100:9:100:31 | simple.test | test.py:101:10:101:10 | simple.test |
| test.py:105:12:105:14 | .x = simple.test | test.py:106:10:106:12 | .x = simple.test |
| test.py:106:10:106:12 | .x = simple.test | test.py:106:10:106:14 | simple.test |
| test.py:110:11:110:16 | .dangerous = simple.test | test.py:110:11:110:26 | simple.test |
| test.py:110:11:110:26 | simple.test | test.py:111:10:111:10 | .x = simple.test |
| test.py:111:10:111:10 | .x = simple.test | test.py:111:10:111:12 | simple.test |
| test.py:115:11:115:16 | .dangerous = simple.test | test.py:115:11:115:26 | simple.test |
| test.py:115:11:115:26 | simple.test | test.py:116:13:116:13 | .x = simple.test |
| test.py:116:9:116:14 | .x = simple.test | test.py:117:12:117:12 | .x = simple.test |
| test.py:116:13:116:13 | .x = simple.test | test.py:116:9:116:14 | .x = simple.test |
| test.py:117:12:117:12 | .x = simple.test | test.py:105:12:105:14 | .x = simple.test |
| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test |
| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test |
| test.py:155:20:155:38 | simple.test | test.py:156:6:156:11 | simple.test |
| test.py:159:10:159:15 | simple.test | test.py:160:14:160:14 | simple.test |
| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test |
| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test |
| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test |
| test.py:195:9:195:14 | simple.test | test.py:197:14:197:14 | simple.test |
| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test |
| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test |
| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test |
| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test |
| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test |
| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple |
| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test |
| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test |
| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test |
| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test |
#select
| carrier.py:18:10:18:15 | Attribute | carrier.py:17:25:17:30 | simple.test | carrier.py:18:10:18:15 | simple.test | $@ flows to $@. | carrier.py:17:25:17:30 | SOURCE | simple.test | carrier.py:18:10:18:15 | Attribute | simple.test |
| carrier.py:26:10:26:21 | Attribute() | carrier.py:25:29:25:34 | simple.test | carrier.py:26:10:26:21 | simple.test | $@ flows to $@. | carrier.py:25:29:25:34 | SOURCE | simple.test | carrier.py:26:10:26:21 | Attribute() | simple.test |
| deep.py:22:6:22:6 | x | deep.py:20:8:20:13 | simple.test | deep.py:22:6:22:6 | simple.test | $@ flows to $@. | deep.py:20:8:20:13 | SOURCE | simple.test | deep.py:22:6:22:6 | x | simple.test |

View File

@@ -5,7 +5,6 @@
import python
import semmle.python.dataflow.TaintTracking
import TaintLib
import semmle.python.security.Paths
from SimpleConfig config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)

View File

@@ -1,29 +1,3 @@
edges
| example.py:17:14:17:21 | Dilbert | example.py:18:13:18:18 | Dilbert |
| example.py:17:14:17:21 | Wally | example.py:18:13:18:18 | Wally |
| example.py:22:14:22:21 | Dilbert | example.py:23:20:23:25 | Dilbert |
| example.py:23:14:23:26 | Dilbert | example.py:24:13:24:18 | Dilbert |
| example.py:23:20:23:25 | Dilbert | example.py:23:14:23:26 | Dilbert |
| example.py:28:14:28:21 | Dilbert | example.py:29:13:29:18 | Dilbert |
| example.py:28:14:28:21 | Wally | example.py:29:13:29:18 | Wally |
| example.py:33:14:33:21 | Dilbert | example.py:34:24:34:29 | Dilbert |
| example.py:34:12:34:30 | .worker = Dilbert | example.py:37:20:37:23 | .worker = Dilbert |
| example.py:34:24:34:29 | Dilbert | example.py:34:12:34:30 | .worker = Dilbert |
| example.py:37:14:37:31 | Dilbert | example.py:39:13:39:18 | Dilbert |
| example.py:37:20:37:23 | .worker = Dilbert | example.py:37:20:37:30 | Dilbert |
| example.py:37:20:37:30 | Dilbert | example.py:37:14:37:31 | Dilbert |
| example.py:57:14:57:21 | Dilbert | example.py:58:22:58:27 | Dilbert |
| example.py:57:14:57:21 | Wally | example.py:58:22:58:27 | Wally |
| example.py:58:14:58:28 | Dilbert | example.py:60:13:60:18 | Dilbert |
| example.py:58:14:58:28 | Wally | example.py:60:13:60:18 | Wally |
| example.py:58:22:58:27 | Dilbert | example.py:58:14:58:28 | Dilbert |
| example.py:58:22:58:27 | Wally | example.py:58:14:58:28 | Wally |
| example.py:64:14:64:21 | Dilbert | example.py:65:20:65:25 | Dilbert |
| example.py:65:14:65:26 | Dilbert | example.py:66:22:66:27 | Dilbert |
| example.py:65:20:65:25 | Dilbert | example.py:65:14:65:26 | Dilbert |
| example.py:66:14:66:28 | Dilbert | example.py:68:13:68:18 | Dilbert |
| example.py:66:22:66:27 | Dilbert | example.py:66:14:66:28 | Dilbert |
#select
| example.py:18:13:18:18 | worker | example.py:17:14:17:21 | Dilbert | example.py:18:13:18:18 | Dilbert | $@ goes to a $@. | example.py:17:14:17:21 | ENGINEER | Dilbert | example.py:18:13:18:18 | worker | meeting |
| example.py:18:13:18:18 | worker | example.py:17:14:17:21 | Wally | example.py:18:13:18:18 | Wally | $@ goes to a $@. | example.py:17:14:17:21 | ENGINEER | Wally | example.py:18:13:18:18 | worker | meeting |
| example.py:24:13:24:18 | worker | example.py:22:14:22:21 | Dilbert | example.py:24:13:24:18 | Dilbert | $@ goes to a $@. | example.py:22:14:22:21 | ENGINEER | Dilbert | example.py:24:13:24:18 | worker | meeting |

View File

@@ -7,7 +7,6 @@
import python
import DilbertConfig
import semmle.python.security.Paths
from DilbertConfig config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)

View File

@@ -1,27 +0,0 @@
| test.py:10:11:10:47 | test.py:10 | MyException() | exception.kind |
| test.py:15:25:15:25 | test.py:15 | e | exception.kind |
| test.py:16:13:16:34 | test.py:16 | Attribute() | exception.info |
| test.py:17:15:17:15 | test.py:17 | s | exception.info |
| test.py:19:13:19:36 | test.py:19 | Attribute() | [exception.info] |
| test.py:20:13:20:37 | test.py:20 | Attribute() | [exception.info] |
| test.py:21:13:21:36 | test.py:21 | Attribute() | [exception.info] |
| test.py:21:35:21:35 | test.py:21 | t | [exception.info] |
| test.py:22:13:22:58 | test.py:22 | Attribute() | [exception.info] |
| test.py:23:13:23:57 | test.py:23 | Attribute() | [exception.info] |
| test.py:24:13:24:35 | test.py:24 | Attribute() | [exception.info] |
| test.py:25:13:25:36 | test.py:25 | Attribute() | [exception.info] |
| test.py:26:25:26:25 | test.py:26 | e | exception.kind |
| test.py:26:25:26:33 | test.py:26 | Attribute | exception.info |
| test.py:26:25:26:41 | test.py:26 | Tuple | [[exception.info]] |
| test.py:26:25:26:41 | test.py:26 | Tuple | [exception.info] |
| test.py:26:36:26:36 | test.py:26 | e | exception.kind |
| test.py:26:36:26:41 | test.py:26 | Attribute | [exception.info] |
| test.py:27:19:27:19 | test.py:27 | t | [exception.info] |
| test.py:27:22:27:22 | test.py:27 | u | [exception.info] |
| test.py:27:25:27:25 | test.py:27 | v | [exception.info] |
| test.py:27:28:27:28 | test.py:27 | w | [exception.info] |
| test.py:27:31:27:31 | test.py:27 | x | [exception.info] |
| test.py:27:34:27:34 | test.py:27 | y | [exception.info] |
| test.py:27:37:27:37 | test.py:27 | z | [exception.info] |
| test.py:27:40:27:46 | test.py:27 | message | exception.info |
| test.py:27:49:27:52 | test.py:27 | args | [exception.info] |

View File

@@ -1,7 +0,0 @@
import python
import semmle.python.security.Exceptions
import semmle.python.web.HttpResponse
from TaintedNode node
where not node.getLocation().getFile().inStdlib()
select node.getLocation(), node.getNode().asAstNode().toString(), node.getTaintKind()

View File

@@ -1,10 +0,0 @@
| test.py:10 | MyException() | exception.kind |
| test.py:15 | e | exception.kind |
| test.py:16 | Attribute() | exception.info |
| test.py:19 | Attribute() | [exception.info] |
| test.py:20 | Attribute() | [exception.info] |
| test.py:21 | Attribute() | [exception.info] |
| test.py:22 | Attribute() | [exception.info] |
| test.py:23 | Attribute() | [exception.info] |
| test.py:24 | Attribute() | [exception.info] |
| test.py:25 | Attribute() | [exception.info] |

View File

@@ -1,9 +0,0 @@
import python
import semmle.python.security.Exceptions
import semmle.python.web.HttpResponse
from TaintSource src, TaintKind kind
where
src.isSourceOf(kind) and
not src.getLocation().getFile().inStdlib()
select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind

View File

@@ -1,16 +0,0 @@
| Taint [exception.info] | test.py:19 | Attribute() | | --> | Taint [exception.info] | test.py:21 | t | |
| Taint [exception.info] | test.py:19 | Attribute() | | --> | Taint [exception.info] | test.py:27 | t | |
| Taint [exception.info] | test.py:20 | Attribute() | | --> | Taint [exception.info] | test.py:27 | u | |
| Taint [exception.info] | test.py:21 | Attribute() | | --> | Taint [exception.info] | test.py:27 | v | |
| Taint [exception.info] | test.py:22 | Attribute() | | --> | Taint [exception.info] | test.py:27 | w | |
| Taint [exception.info] | test.py:23 | Attribute() | | --> | Taint [exception.info] | test.py:27 | x | |
| Taint [exception.info] | test.py:24 | Attribute() | | --> | Taint [exception.info] | test.py:27 | y | |
| Taint [exception.info] | test.py:25 | Attribute() | | --> | Taint [exception.info] | test.py:27 | z | |
| Taint [exception.info] | test.py:26 | Attribute | | --> | Taint [[exception.info]] | test.py:26 | Tuple | |
| Taint [exception.info] | test.py:26 | Attribute | | --> | Taint [exception.info] | test.py:27 | args | |
| Taint exception.info | test.py:16 | Attribute() | | --> | Taint exception.info | test.py:17 | s | |
| Taint exception.info | test.py:26 | Attribute | | --> | Taint [exception.info] | test.py:26 | Tuple | |
| Taint exception.info | test.py:26 | Attribute | | --> | Taint exception.info | test.py:27 | message | |
| Taint exception.kind | test.py:15 | e | | --> | Taint exception.kind | test.py:26 | e | |
| Taint exception.kind | test.py:26 | e | | --> | Taint [exception.info] | test.py:26 | Attribute | |
| Taint exception.kind | test.py:26 | e | | --> | Taint exception.info | test.py:26 | Attribute | |

View File

@@ -1,12 +0,0 @@
import python
import semmle.python.security.Exceptions
import semmle.python.web.HttpResponse
from TaintedNode n, TaintedNode s
where
s = n.getASuccessor() and
not n.getLocation().getFile().inStdlib() and
not s.getLocation().getFile().inStdlib()
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getNode().toString(),
n.getContext(), " --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(),
s.getNode().toString(), s.getContext()

View File

@@ -1,34 +0,0 @@
from __future__ import print_function
import traceback
import sys
class MyException(Exception):
pass
def raise_secret_exception():
raise MyException("Message", "secret info")
def foo():
try:
raise_secret_exception()
except Exception as e:
s = traceback.format_exc()
print(s)
etype, evalue, tb = sys.exc_info()
t = traceback.extract_tb(tb)
u = traceback.extract_stack()
v = traceback.format_list(t)
w = traceback.format_exception_only(etype, evalue)
x = traceback.format_exception(etype, evalue, tb)
y = traceback.format_tb(tb)
z = traceback.format_stack()
message, args = e.message, e.args
print(tb, t, u, v, w, x, y, z, message, args)
foo()
#For test to find stdlib
import os

View File

@@ -1,45 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class FooSource extends TaintSource {
FooSource() { this.(CallNode).getFunction().(NameNode).getId() = "foo_source" }
override predicate isSourceOf(TaintKind kind) { kind instanceof UntrustedStringKind }
override string toString() { result = "FooSource" }
}
class FooSink extends TaintSink {
FooSink() {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "foo_sink" and
call.getAnArg() = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof UntrustedStringKind }
override string toString() { result = "FooSink" }
}
class FooConfig extends TaintTracking::Configuration {
FooConfig() { this = "FooConfig" }
override predicate isSource(TaintTracking::Source source) { source instanceof FooSource }
override predicate isSink(TaintTracking::Sink sink) { sink instanceof FooSink }
}
class BarSink extends TaintSink {
BarSink() {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "bar_sink" and
call.getAnArg() = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof UntrustedStringKind }
override string toString() { result = "BarSink" }
}

View File

@@ -1 +0,0 @@
| test.py:16:9:16:20 | foo_source() | test.py:17:14:17:14 | x |

View File

@@ -1,6 +0,0 @@
import python
import Config
from FooConfig config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)
select src.getSource(), sink.getSink()

View File

@@ -1,22 +0,0 @@
def foo_source():
return 'foo'
def foo_sink(x):
if x == 'foo':
print('fire the foo missiles')
def bar_sink(x):
if x == 'bar':
print('fire the bar missiles')
def should_report():
x = foo_source()
foo_sink(x)
def should_not_report():
x = foo_source()
bar_sink(x)

View File

@@ -1,7 +1,5 @@
import python
import semmle.python.dataflow.TaintTracking
/* Standard library sink */
import semmle.python.security.injection.Command
class TestKind extends TaintKind {
TestKind() { this = "test" }

View File

@@ -1,7 +0,0 @@
| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:21 | Pi(urlsplit_res_0) [true] |
| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:24 | Pi(urlsplit_res_3) [true] |
| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:27 | Pi(urlsplit_res_6) [true] |
| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:30 | Pi(urlsplit_res_9) [true] |
| string equality sanitizer | externally controlled string | test.py:21 | Pi(urlsplit_res_0) [true] |
| string equality sanitizer | externally controlled string | test.py:24 | Pi(urlsplit_res_3) [true] |
| string equality sanitizer | externally controlled string | test.py:27 | Pi(urlsplit_res_6) [true] |

View File

@@ -1,6 +0,0 @@
import python
import Taint
from Sanitizer s, TaintKind taint, PyEdgeRefinement test
where s.sanitizingEdge(taint, test)
select s, taint, test.getTest().getLocation().toString(), test.getRepresentation()

View File

@@ -1,45 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}
class TestConfig extends TaintTracking::Configuration {
TestConfig() { this = "TestConfig" }
override predicate isSanitizer(Sanitizer sanitizer) {
sanitizer instanceof UrlsplitUrlparseTempSanitizer
}
override predicate isSource(TaintTracking::Source source) {
source instanceof SimpleSource
or
source instanceof ListSource
or
source instanceof DictSource
}
override predicate isSink(TaintTracking::Sink sink) { none() }
}

View File

@@ -1,15 +0,0 @@
| test.py:13 | test_basic | a | externally controlled string |
| test.py:13 | test_basic | b | externally controlled string |
| test.py:13 | test_basic | c | externally controlled string |
| test.py:13 | test_basic | d | externally controlled string |
| test.py:13 | test_basic | urlsplit_res | [externally controlled string] |
| test.py:19 | test_sanitizer | Attribute | externally controlled string |
| test.py:22 | test_sanitizer | Attribute | NO TAINT |
| test.py:25 | test_sanitizer | Subscript | NO TAINT |
| test.py:28 | test_sanitizer | Attribute | NO TAINT |
| test.py:31 | test_sanitizer | Attribute | NO TAINT |
| test.py:34 | test_sanitizer | Attribute | externally controlled string |
| test.py:44 | test_namedtuple | a | NO TAINT |
| test.py:44 | test_namedtuple | b | NO TAINT |
| test.py:44 | test_namedtuple | c | NO TAINT |
| test.py:44 | test_namedtuple | d | NO TAINT |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,44 +0,0 @@
from six.moves.urllib.parse import urlsplit
# Currently we don't have support for namedtuples in general, but do have special support
# for `urlsplit` (and `urlparse`)
def test_basic():
tainted_string = TAINTED_STRING
urlsplit_res = urlsplit(tainted_string)
a = urlsplit_res.netloc # field access
b = urlsplit_res.hostname # property
c = urlsplit_res[3] # indexing
_, _, d, _, _ = urlsplit(tainted_string) # unpacking
test(a, b, c, d, urlsplit_res)
def test_sanitizer():
tainted_string = TAINTED_STRING
urlsplit_res = urlsplit(tainted_string)
test(urlsplit_res.netloc) # should be tainted
if urlsplit_res.netloc == "OK":
test(urlsplit_res.netloc)
if urlsplit_res[2] == "OK":
test(urlsplit_res[0])
if urlsplit_res.netloc == "OK":
test(urlsplit_res.path) # FN
if urlsplit_res.netloc in ["OK"]:
test(urlsplit_res.netloc)
if urlsplit_res.netloc in ["OK", non_constant()]:
test(urlsplit_res.netloc) # should be tainted
def test_namedtuple():
tainted_string = TAINTED_STRING
Point = namedtuple('Point', ['x', 'y'])
p = Point('safe', tainted_string)
a = p.x
b = p.y
c = p[0]
d = p[1]
test(a, b, c, d) # TODO: FN, at least p.y and p[1] should be tainted

View File

@@ -1,44 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.Exceptions
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}
class ExceptionInfoSource extends TaintSource {
ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo }
override string toString() { result = "Exception info source" }
}
class ExternalFileObjectSource extends TaintSource {
ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject }
override string toString() { result = "Tainted file source" }
}

View File

@@ -1,162 +0,0 @@
| Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | | --> | Taint [[externally controlled string]] | test.py:75 | test.py:75:19:75:19 | d | |
| Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:10:75:10 | a | |
| Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:13:75:13 | b | |
| Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:40 | Subscript | |
| Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:41 | Subscript | |
| Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:41 | Subscript | |
| Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:33 | Subscript | |
| Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:38 | Subscript | |
| Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info |
| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:12:46:22 | func() | p1 = exception.info |
| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info |
| Taint exception.info | test.py:49 | test.py:49:12:49:33 | TAINTED_EXCEPTION_INFO | | --> | Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | |
| Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | | --> | Taint exception.info | test.py:51 | test.py:51:10:51:12 | res | |
| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info |
| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | |
| Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info | --> | Taint exception.info | test.py:54 | test.py:54:12:54:14 | arg | p0 = exception.info |
| Taint externally controlled string | test.py:6 | test.py:6:22:6:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | |
| Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | | --> | Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:9 | a | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:10:11:10 | a | |
| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:9 | b | |
| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:11 | test.py:11:13:11:13 | b | |
| Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:16:11:16 | c | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:10:22:10 | a | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:13:22:13 | b | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:16:22:16 | c | |
| Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | |
| Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:19:22:19 | d | |
| Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | | --> | Taint externally controlled string | test.py:22 | test.py:22:22:22:22 | e | |
| Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | | --> | Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | |
| Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | | --> | Taint externally controlled string | test.py:22 | test.py:22:25:22:25 | f | |
| Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | | --> | Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | |
| Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | |
| Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:28:22:28 | g | |
| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:26 | test.py:26:8:26:21 | tainted_string | |
| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:29 | test.py:29:14:29:27 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:8:33:21 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:34:33:47 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:36 | test.py:36:14:36:27 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | |
| Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | | --> | Taint externally controlled string | test.py:43 | test.py:43:10:43:10 | a | |
| Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | |
| Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:13:43:13 | b | |
| Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | |
| Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:16:43:16 | c | |
| Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | | --> | Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | |
| Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:12:46:22 | func() | p1 = externally controlled string |
| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string | --> | Taint externally controlled string | test.py:54 | test.py:54:12:54:14 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:57 | test.py:57:11:57:24 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | |
| Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | | --> | Taint externally controlled string | test.py:59 | test.py:59:10:59:12 | res | |
| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | |
| Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | |
| Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | |
| Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | | --> | Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | |
| Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | | --> | Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | |
| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | |
| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:82 | test.py:82:12:82:25 | tainted_string | |
| Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | |
| Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | | --> | Taint externally controlled string | test.py:85 | test.py:85:10:85:10 | a | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | |
| Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:35 | Attribute() | |
| Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:33 | Attribute() | |
| Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:31 | Attribute() | |
| Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:38 | Attribute() | |
| Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | |
| Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:54 | Attribute() | |
| Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:35 | Attribute() | |
| Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:37 | Attribute() | |
| Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:46 | Attribute() | |
| Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:33 | Attribute() | |
| Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:30 | Attribute() | |
| Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:31 | Attribute() | |
| Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:35 | Attribute() | |
| Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:103 | test.py:103:9:103:37 | Attribute() | |
| Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | |
| Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:42 | Attribute() | |
| Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:33 | Attribute() | |
| Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:107 | test.py:107:9:107:38 | Attribute() | |
| Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | |
| Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:109 | test.py:109:9:109:37 | Attribute() | |
| Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | |
| Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:31 | Attribute() | |
| Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:112 | test.py:112:9:112:30 | Attribute() | |
| Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | |
| Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:114 | test.py:114:9:114:35 | Attribute() | |
| Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | |
| Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:30 | Attribute() | |
| Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:33 | Attribute() | |
| Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:30 | Attribute() | |
| Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:30 | Attribute() | |
| Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:33 | Attribute() | |
| Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | | --> | Taint externally controlled string | test.py:134 | test.py:134:14:134:17 | line | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:128 | test.py:128:9:128:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | |
| Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | | --> | Taint externally controlled string | test.py:129 | test.py:129:9:129:27 | Attribute() | |
| Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | | --> | Taint externally controlled string | test.py:130 | test.py:130:9:130:31 | Attribute() | |
| Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | | --> | Taint [externally controlled string] | test.py:131 | test.py:131:9:131:32 | Attribute() | |
| Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | | --> | Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:10:11:10 | a | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:13:11:13 | b | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:16:11:16 | c | |
| Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | | --> | Taint {externally controlled string} | test.py:75 | test.py:75:16:75:16 | c | |

View File

@@ -1,11 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from TaintedNode n, TaintedNode s
where
n.getLocation().getFile().getShortName() = "test.py" and
s.getLocation().getFile().getShortName() = "test.py" and
s = n.getASuccessor()
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(),
" --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext()

View File

@@ -1,63 +0,0 @@
| test.py:11 | test_json | a | externally controlled string |
| test.py:11 | test_json | a | json[externally controlled string] |
| test.py:11 | test_json | b | externally controlled string |
| test.py:11 | test_json | b | json[externally controlled string] |
| test.py:11 | test_json | c | externally controlled string |
| test.py:11 | test_json | c | json[externally controlled string] |
| test.py:22 | test_str | a | externally controlled string |
| test.py:22 | test_str | b | externally controlled string |
| test.py:22 | test_str | c | externally controlled string |
| test.py:22 | test_str | d | externally controlled string |
| test.py:22 | test_str | e | externally controlled string |
| test.py:22 | test_str | f | externally controlled string |
| test.py:22 | test_str | g | externally controlled string |
| test.py:27 | test_const_sanitizer1 | tainted_string | NO TAINT |
| test.py:29 | test_const_sanitizer1 | tainted_string | externally controlled string |
| test.py:34 | test_const_sanitizer2 | tainted_string | NO TAINT |
| test.py:36 | test_const_sanitizer2 | tainted_string | externally controlled string |
| test.py:43 | test_str2 | a | externally controlled string |
| test.py:43 | test_str2 | b | externally controlled string |
| test.py:43 | test_str2 | c | externally controlled string |
| test.py:51 | test_exc_info | res | exception.info |
| test.py:59 | test_untrusted | res | externally controlled string |
| test.py:75 | test_urlsplit_urlparse | a | [externally controlled string] |
| test.py:75 | test_urlsplit_urlparse | b | [externally controlled string] |
| test.py:75 | test_urlsplit_urlparse | c | {externally controlled string} |
| test.py:75 | test_urlsplit_urlparse | d | [[externally controlled string]] |
| test.py:85 | test_method_reference | a | externally controlled string |
| test.py:85 | test_method_reference | b | NO TAINT |
| test.py:91 | test_str_methods | Attribute() | externally controlled string |
| test.py:92 | test_str_methods | Attribute() | externally controlled string |
| test.py:93 | test_str_methods | Attribute() | externally controlled string |
| test.py:94 | test_str_methods | Attribute() | externally controlled string |
| test.py:95 | test_str_methods | Attribute() | externally controlled string |
| test.py:96 | test_str_methods | Attribute() | externally controlled string |
| test.py:97 | test_str_methods | Attribute() | externally controlled string |
| test.py:98 | test_str_methods | Attribute() | externally controlled string |
| test.py:99 | test_str_methods | Attribute() | externally controlled string |
| test.py:100 | test_str_methods | Attribute() | externally controlled string |
| test.py:101 | test_str_methods | Attribute() | externally controlled string |
| test.py:102 | test_str_methods | Attribute() | externally controlled string |
| test.py:103 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:104 | test_str_methods | Subscript | externally controlled string |
| test.py:105 | test_str_methods | Attribute() | externally controlled string |
| test.py:106 | test_str_methods | Attribute() | externally controlled string |
| test.py:107 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:108 | test_str_methods | Subscript | externally controlled string |
| test.py:109 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:110 | test_str_methods | Subscript | externally controlled string |
| test.py:111 | test_str_methods | Attribute() | externally controlled string |
| test.py:112 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:113 | test_str_methods | Subscript | externally controlled string |
| test.py:114 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:115 | test_str_methods | Subscript | externally controlled string |
| test.py:116 | test_str_methods | Attribute() | externally controlled string |
| test.py:117 | test_str_methods | Attribute() | externally controlled string |
| test.py:118 | test_str_methods | Attribute() | externally controlled string |
| test.py:121 | test_str_methods | Attribute() | externally controlled string |
| test.py:122 | test_str_methods | Attribute() | externally controlled string |
| test.py:128 | test_tainted_file | tainted_file | file[externally controlled string] |
| test.py:129 | test_tainted_file | Attribute() | externally controlled string |
| test.py:130 | test_tainted_file | Attribute() | externally controlled string |
| test.py:131 | test_tainted_file | Attribute() | [externally controlled string] |
| test.py:134 | test_tainted_file | line | externally controlled string |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,134 +0,0 @@
import json
from copy import copy
import sys
def test_json():
tainted_string = TAINTED_STRING
tainted_json = json.loads(tainted_string)
a = tainted_json["x"]
b = a.get("y")
c = b["z"]
test(a, b, c)
def test_str():
tainted_string = TAINTED_STRING
a = tainted_string.ljust(8)
b = tainted_string.copy()
c = tainted_string[:]
d = tainted_string[::2]
e = reversed(tainted_string)
f = copy(tainted_string)
g = tainted_string.strip()
test(a, b, c, d, e, f, g)
def test_const_sanitizer1():
tainted_string = TAINTED_STRING
if tainted_string == "OK":
test(tainted_string) # not tainted
else:
test(tainted_string) # still tainted
def test_const_sanitizer2():
tainted_string = TAINTED_STRING
if tainted_string == "OK" or tainted_string == "ALSO_OK":
test(tainted_string) # not tainted
else:
test(tainted_string) # still tainted
def test_str2():
tainted_string = TAINTED_STRING
a = str(tainted_string)
b = bytes(tainted_string) # This is an error in Python 3
c = bytes(tainted_string, encoding="utf8") # This is an error in Python 2
test(a, b, c)
def cross_over(func, taint):
return func(taint)
def test_exc_info():
info = TAINTED_EXCEPTION_INFO
res = cross_over(exc_info_call, info)
test(res)
def exc_info_call(arg):
return arg
def test_untrusted():
ext = TAINTED_STRING
res = cross_over(untrusted_call, ext)
test(res)
def exc_untrusted_call(arg):
return arg
if sys.version_info[0] == 2:
from urlparse import urlsplit, urlparse, parse_qs, parse_qsl
if sys.version_info[0] == 3:
from urllib.parse import urlsplit, urlparse, parse_qs, parse_qsl
def test_urlsplit_urlparse():
tainted_string = TAINTED_STRING
a = urlsplit(tainted_string)
b = urlparse(tainted_string)
c = parse_qs(tainted_string)
d = parse_qsl(tainted_string)
test(a, b, c, d)
def test_method_reference():
tainted_string = TAINTED_STRING
a = tainted_string.title()
func = tainted_string.title
b = func()
test(a, b) # TODO: `b` not tainted
def test_str_methods():
tainted_string = TAINTED_STRING
test(
tainted_string.capitalize(),
tainted_string.casefold(),
tainted_string.center(),
tainted_string.encode('utf-8'),
tainted_string.encode('utf-8').decode('utf-8'),
tainted_string.expandtabs(),
tainted_string.format(foo=42),
tainted_string.format_map({'foo': 42}),
tainted_string.ljust(100),
tainted_string.lower(),
tainted_string.lstrip(),
tainted_string.lstrip('w.'),
tainted_string.partition(';'),
tainted_string.partition(';')[0],
tainted_string.replace('/', '', 1),
tainted_string.rjust(100),
tainted_string.rpartition(';'),
tainted_string.rpartition(';')[2],
tainted_string.rsplit(';', 4),
tainted_string.rsplit(';', 4)[-1],
tainted_string.rstrip(),
tainted_string.split(),
tainted_string.split()[0],
tainted_string.splitlines(),
tainted_string.splitlines()[0],
tainted_string.strip(),
tainted_string.swapcase(),
tainted_string.title(),
# ignoring, as I have never seen this in practice
# tainted_string.translate(translation_table),
tainted_string.upper(),
tainted_string.zfill(100),
)
def test_tainted_file():
tainted_file = TAINTED_FILE
test(
tainted_file,
tainted_file.read(),
tainted_file.readline(),
tainted_file.readlines(),
)
for line in tainted_file:
test(line)

View File

@@ -1,27 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}

View File

@@ -1,41 +0,0 @@
| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | |
| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | |
| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | |
| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:22:23:22 | b | |
| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:25:23:25 | c | |
| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:10:23:11 | a1 | |
| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:14:23:15 | a2 | |
| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:18:23:19 | a3 | |
| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:22:27:22 | b | |
| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:25:27:25 | c | |
| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:10:27:11 | a1 | |
| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:14:27:15 | a2 | |
| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:18:27:19 | a3 | |
| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:22:31:22 | b | |
| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:25:31:25 | c | |
| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:10:31:11 | a1 | |
| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:14:31:15 | a2 | |
| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:18:31:19 | a3 | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:10:48:10 | a | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:13:48:13 | b | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:16:48:16 | c | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:19:48:19 | d | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:22:48:22 | e | |
| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:25:48:25 | f | |
| Taint [externally controlled string] | test.py:6 | test.py:6:9:6:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | |
| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:10:8:10 | a | |
| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:13:8:13 | b | |
| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:16:8:16 | c | |
| Taint [externally controlled string] | test.py:12 | test.py:12:9:12:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | |
| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:10:14:10 | a | |
| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:13:14:13 | b | |
| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:16:14:16 | c | |
| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:11:19:11 | l | |
| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:14:19:14 | l | |
| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:17:19:17 | l | |
| Taint [externally controlled string] | test.py:19 | test.py:19:11:19:11 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | |
| Taint [externally controlled string] | test.py:19 | test.py:19:14:19:14 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | |
| Taint [externally controlled string] | test.py:19 | test.py:19:17:19:17 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | |
| Taint [externally controlled string] | test.py:43 | test.py:43:20:43:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:47 | test.py:47:28:47:39 | tainted_list | |
| Taint [externally controlled string] | test.py:47 | test.py:47:28:47:39 | tainted_list | | --> | Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | |
| Taint [externally controlled string] | test.py:55 | test.py:55:27:55:38 | TAINTED_LIST | | --> | Taint [[externally controlled string]] | test.py:55 | test.py:55:25:55:40 | List | |

View File

@@ -1,11 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from TaintedNode n, TaintedNode s
where
n.getLocation().getFile().getShortName() = "test.py" and
s.getLocation().getFile().getShortName() = "test.py" and
s = n.getASuccessor()
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(),
" --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext()

View File

@@ -1,33 +0,0 @@
| test.py:8 | unpacking | a | externally controlled string |
| test.py:8 | unpacking | b | externally controlled string |
| test.py:8 | unpacking | c | externally controlled string |
| test.py:14 | unpacking_to_list | a | externally controlled string |
| test.py:14 | unpacking_to_list | b | externally controlled string |
| test.py:14 | unpacking_to_list | c | externally controlled string |
| test.py:23 | nested | a1 | externally controlled string |
| test.py:23 | nested | a2 | externally controlled string |
| test.py:23 | nested | a3 | externally controlled string |
| test.py:23 | nested | b | [externally controlled string] |
| test.py:23 | nested | c | [externally controlled string] |
| test.py:27 | nested | a1 | externally controlled string |
| test.py:27 | nested | a2 | externally controlled string |
| test.py:27 | nested | a3 | externally controlled string |
| test.py:27 | nested | b | [externally controlled string] |
| test.py:27 | nested | c | [externally controlled string] |
| test.py:31 | nested | a1 | externally controlled string |
| test.py:31 | nested | a2 | externally controlled string |
| test.py:31 | nested | a3 | externally controlled string |
| test.py:31 | nested | b | [externally controlled string] |
| test.py:31 | nested | c | [externally controlled string] |
| test.py:38 | unpack_from_set | a | NO TAINT |
| test.py:38 | unpack_from_set | b | NO TAINT |
| test.py:38 | unpack_from_set | c | NO TAINT |
| test.py:48 | contrived_1 | a | externally controlled string |
| test.py:48 | contrived_1 | b | externally controlled string |
| test.py:48 | contrived_1 | c | externally controlled string |
| test.py:48 | contrived_1 | d | externally controlled string |
| test.py:48 | contrived_1 | e | externally controlled string |
| test.py:48 | contrived_1 | f | externally controlled string |
| test.py:56 | contrived_2 | a | NO TAINT |
| test.py:56 | contrived_2 | b | NO TAINT |
| test.py:56 | contrived_2 | c | NO TAINT |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,58 +0,0 @@
def test(*args):
pass
def unpacking():
l = TAINTED_LIST
a, b, c = l
test(a, b, c)
def unpacking_to_list():
l = TAINTED_LIST
[a, b, c] = l
test(a, b, c)
def nested():
l = TAINTED_LIST
ll = [l, l, l]
# list
[[a1, a2, a3], b, c] = ll
test(a1, a2, a3, b, c)
# tuple
((a1, a2, a3), b, c) = ll
test(a1, a2, a3, b, c)
# mixed
[(a1, a2, a3), b, c] = ll
test(a1, a2, a3, b, c)
def unpack_from_set():
# no guarantee on ordering ... don't know why you would ever do this
a, b, c = {"foo", "bar", TAINTED_STRING}
# either all should be tainted, or none of them
test(a, b, c)
def contrived_1():
# A contrived example. Don't know why anyone would ever actually do this.
tainted_list = TAINTED_LIST
no_taint_list = [1,2,3]
# We don't handle this case currently, since we mark `d`, `e` and `f` as tainted.
(a, b, c), (d, e, f) = tainted_list, no_taint_list
test(a, b, c, d, e, f)
def contrived_2():
# A contrived example. Don't know why anyone would ever actually do this.
# We currently only handle taint nested 2 levels.
[[[ (a,b,c) ]]] = [[[ TAINTED_LIST ]]]
test(a, b, c)
# For Python 3, see https://www.python.org/dev/peps/pep-3132/

View File

@@ -1,8 +1,16 @@
edges
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
| test.py:5:1:5:8 | GSSA Variable USERNAME | test.py:14:18:14:25 | ControlFlowNode for USERNAME |
| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:1:5:8 | GSSA Variable USERNAME |
| test.py:6:1:6:8 | GSSA Variable PASSWORD | test.py:15:18:15:25 | ControlFlowNode for PASSWORD |
| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:1:6:8 | GSSA Variable PASSWORD |
nodes
| test.py:5:1:5:8 | GSSA Variable USERNAME | semmle.label | GSSA Variable USERNAME |
| test.py:5:12:5:24 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:6:1:6:8 | GSSA Variable PASSWORD | semmle.label | GSSA Variable PASSWORD |
| test.py:6:12:6:25 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:14:18:14:25 | ControlFlowNode for USERNAME | semmle.label | ControlFlowNode for USERNAME |
| test.py:15:18:15:25 | ControlFlowNode for PASSWORD | semmle.label | ControlFlowNode for PASSWORD |
subpaths
#select
| test.py:5:12:5:24 | Str | test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | This hardcoded value is $@. | test.py:14:18:14:25 | USERNAME | used as credentials |
| test.py:6:12:6:25 | Str | test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | This hardcoded value is $@. | test.py:15:18:15:25 | PASSWORD | used as credentials |
| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:12:5:24 | ControlFlowNode for Str | test.py:14:18:14:25 | ControlFlowNode for USERNAME | This hardcoded value is $@. | test.py:14:18:14:25 | ControlFlowNode for USERNAME | used as credentials |
| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:12:6:25 | ControlFlowNode for Str | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | This hardcoded value is $@. | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | used as credentials |