Merge branch 'master' into python-encapsulate-builtins

This commit is contained in:
Taus
2019-03-27 15:40:34 +01:00
committed by GitHub
342 changed files with 22694 additions and 2224 deletions

View File

@@ -15,6 +15,14 @@
import python
import semmle.python.Comparisons
/* Holds if the comparison `comp` is of the complex form `a op b op c` and not of
* the simple form `a op b`.
*/
private predicate is_complex(Expr comp) {
exists(comp.(Compare).getOp(1))
or
is_complex(comp.(UnaryExpr).getOperand())
}
/** A test is useless if for every block that it controls there is another test that is at least as
* strict and also controls that block.
@@ -22,7 +30,7 @@ import semmle.python.Comparisons
private predicate useless_test(Comparison comp, ComparisonControlBlock controls, boolean isTrue) {
controls.impliesThat(comp.getBasicBlock(), comp, isTrue) and
/* Exclude complex comparisons of form `a < x < y`, as we do not (yet) have perfect flow control for those */
not exists(controls.getTest().getNode().(Compare).getOp(1))
not is_complex(controls.getTest().getNode())
}
private predicate useless_test_ast(AstNode comp, AstNode previous, boolean isTrue) {

View File

@@ -15,10 +15,7 @@ import semmle.python.web.Http
FunctionObject requestFunction() {
exists(ModuleObject req |
req.getName() = "requests" and
result = req.attr(httpVerbLower())
)
result = ModuleObject::named("requests").attr(httpVerbLower())
}
/** requests treats None as the default and all other "falsey" values as False */

View File

@@ -13,25 +13,27 @@
import python
FunctionObject ssl_wrap_socket() {
result = any(ModuleObject ssl | ssl.getName() = "ssl").attr("wrap_socket")
result = ModuleObject::named("ssl").attr("wrap_socket")
}
ClassObject ssl_Context_class() {
result = any(ModuleObject ssl | ssl.getName() = "ssl").attr("SSLContext")
result = ModuleObject::named("ssl").attr("SSLContext")
}
CallNode unsafe_call(string method_name) {
result = ssl_wrap_socket().getACall() and
not exists(result.getArgByName("ssl_version")) and
method_name = "deprecated method ssl.wrap_socket"
or
result = ssl_Context_class().getACall() and
not exists(result.getArgByName("protocol")) and
not exists(result.getArg(0)) and
method_name = "ssl.SSLContext"
}
from CallNode call, string method_name
where
call = unsafe_call(method_name) and
not exists(call.getArgByName("ssl_version"))
call = unsafe_call(method_name)
select call, "Call to " + method_name + " does not specify a protocol, which may result in an insecure default being used."

View File

@@ -34,19 +34,23 @@ string insecure_version_name() {
}
private ModuleObject the_ssl_module() {
result = any(ModuleObject m | m.getName() = "ssl")
result = ModuleObject::named("ssl")
}
private ModuleObject the_pyOpenSSL_module() {
result = any(ModuleObject m | m.getName() = "pyOpenSSL.SSL")
result = ModuleObject::named("pyOpenSSL.SSL")
}
/* A syntactic check for cases where points-to analysis cannot infer the presence of
* a protocol constant, e.g. if it has been removed in later versions of the `ssl`
* library.
*/
predicate probable_insecure_ssl_constant(CallNode call, string insecure_version) {
exists(ControlFlowNode arg | arg = call.getArgByName("ssl_version") |
bindingset[named_argument]
predicate probable_insecure_ssl_constant(CallNode call, string insecure_version, string named_argument) {
exists(ControlFlowNode arg |
arg = call.getArgByName(named_argument) or
arg = call.getArg(0)
|
arg.(AttrNode).getObject(insecure_version).refersTo(the_ssl_module())
or
arg.(NameNode).getId() = insecure_version and
@@ -57,26 +61,28 @@ predicate probable_insecure_ssl_constant(CallNode call, string insecure_version)
)
}
predicate unsafe_ssl_wrap_socket_call(CallNode call, string method_name, string insecure_version) {
predicate unsafe_ssl_wrap_socket_call(CallNode call, string method_name, string insecure_version, string named_argument) {
(
call = ssl_wrap_socket().getACall() and
method_name = "deprecated method ssl.wrap_socket"
method_name = "deprecated method ssl.wrap_socket" and
named_argument = "ssl_version"
or
call = ssl_Context_class().getACall() and
named_argument = "protocol" and
method_name = "ssl.SSLContext"
)
and
insecure_version = insecure_version_name()
and
(
call.getArgByName("ssl_version").refersTo(the_ssl_module().attr(insecure_version))
call.getArgByName(named_argument).refersTo(the_ssl_module().attr(insecure_version))
or
probable_insecure_ssl_constant(call, insecure_version)
probable_insecure_ssl_constant(call, insecure_version, named_argument)
)
}
ClassObject the_pyOpenSSL_Context_class() {
result = any(ModuleObject m | m.getName() = "pyOpenSSL.SSL").attr("Context")
result = ModuleObject::named("pyOpenSSL.SSL").attr("Context")
}
predicate unsafe_pyOpenSSL_Context_call(CallNode call, string insecure_version) {
@@ -87,7 +93,7 @@ predicate unsafe_pyOpenSSL_Context_call(CallNode call, string insecure_version)
from CallNode call, string method_name, string insecure_version
where
unsafe_ssl_wrap_socket_call(call, method_name, insecure_version)
unsafe_ssl_wrap_socket_call(call, method_name, insecure_version, _)
or
unsafe_pyOpenSSL_Context_call(call, insecure_version) and method_name = "pyOpenSSL.SSL.Context"
select call, "Insecure SSL/TLS protocol version " + insecure_version + " specified in call to " + method_name + "."

View File

@@ -23,7 +23,7 @@ FunctionObject temporary_name_function(string mod, string function) {
function = "tempnam"
)
) and
result = any(ModuleObject m | m.getName() = mod).getAttribute(function)
result = ModuleObject::named(mod).attr(function)
}
from Call c, string mod, string function

View File

@@ -35,12 +35,12 @@ string permissive_permission(int p) {
}
predicate chmod_call(CallNode call, FunctionObject chmod, NumericObject num) {
any(ModuleObject os | os.getName() = "os").attr("chmod") = chmod and
ModuleObject::named("os").attr("chmod") = chmod and
chmod.getACall() = call and call.getArg(1).refersTo(num)
}
predicate open_call(CallNode call, FunctionObject open, NumericObject num) {
any(ModuleObject os | os.getName() = "os").attr("open") = open and
ModuleObject::named("os").attr("open") = open and
open.getACall() = call and call.getArg(2).refersTo(num)
}

View File

@@ -40,7 +40,7 @@ predicate possible_reflective_name(string name) {
or
any(ClassObject c).getName() = name
or
any(ModuleObject m).getName() = name
exists(ModuleObject::named(name))
or
exists(Object::builtin(name))
}

View File

@@ -95,6 +95,14 @@ predicate in_raises_test(Expr e) {
)
}
/** Holds if expression has the form of a Python 2 `print >> out, ...` statement */
predicate python2_print(Expr e) {
e.(BinaryExpr).getLeft().(Name).getId() = "print" and
e.(BinaryExpr).getOp() instanceof RShift
or
python2_print(e.(Tuple).getElt(0))
}
predicate no_effect(Expr e) {
not e instanceof StrConst and
not ((StrConst)e).isDocString() and
@@ -107,7 +115,8 @@ predicate no_effect(Expr e) {
not maybe_side_effecting_attribute(sub)
) and
not in_notebook(e) and
not in_raises_test(e)
not in_raises_test(e) and
not python2_print(e)
}
from ExprStmt stmt

View File

@@ -0,0 +1,3 @@
/* For compatibility with other language implementations */
import semmle.python.security.TaintTracking

View File

@@ -51,6 +51,8 @@ ClassObject simple_types(Object obj) {
obj.getOrigin() instanceof Module and result = theModuleType()
or
result.asBuiltin() = obj.asBuiltin().getClass()
or
obj = unknownValue() and result = theUnknownType()
}
private ClassObject comprehension(Expr e) {

View File

@@ -125,13 +125,6 @@ abstract class TaintKind extends string {
*/
predicate additionalFlowStepVar(EssaVariable fromvar, EssaVariable tovar) { none() }
/** Holds if this kind of taint can start from `expr`.
* In other words, is `expr` a source of this kind of taint.
*/
final predicate startsFrom(ControlFlowNode expr) {
expr.(TaintSource).isSourceOf(this, _)
}
/** Holds if this kind of taint "taints" `expr`.
*/
final predicate taints(ControlFlowNode expr) {
@@ -196,16 +189,6 @@ class SequenceKind extends CollectionKind {
}
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
sequence_subscript_taint(tonode, fromnode, this, result)
or
result = this and
(
slice(fromnode, tonode) or
tonode.(BinaryExprNode).getAnOperand() = fromnode
)
or
result = this and TaintFlowImplementation::copyCall(fromnode, tonode)
or
exists(BinaryExprNode mod |
mod = tonode and
mod.getOp() instanceof Mod and
@@ -213,8 +196,6 @@ class SequenceKind extends CollectionKind {
result = this.getItem() and
result.getClass() = theStrType()
)
or
result = this and sequence_call(fromnode, tonode)
}
override TaintKind getTaintOfMethodResult(string name) {
@@ -227,26 +208,42 @@ class SequenceKind extends CollectionKind {
}
/* Helper for getTaintForStep() */
pragma [noinline]
private predicate sequence_subscript_taint(SubscriptNode sub, ControlFlowNode obj, SequenceKind seq, TaintKind key) {
sub.isLoad() and
sub.getValue() = obj and
if sub.getNode().getIndex() instanceof Slice then
seq = key
else
key = seq.getItem()
module SequenceKind {
predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
tonode.(BinaryExprNode).getAnOperand() = fromnode
or
TaintFlowImplementation::copyCall(fromnode, tonode)
or
sequence_call(fromnode, tonode)
or
sequence_subscript_slice(fromnode, tonode)
}
predicate itemFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
sequence_subscript_index(fromnode, tonode)
}
}
/* tonode = fromnode[:] */
private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) {
exists(Slice all |
all = tonode.getIndex().getNode() and
not exists(all.getStart()) and not exists(all.getStop()) and
tonode.getValue() = fromnode
)
/* Helper for sequence flow steps */
pragma [noinline]
private predicate sequence_subscript_index(ControlFlowNode obj, SubscriptNode sub) {
sub.isLoad() and
sub.getValue() = obj and
not sub.getNode().getIndex() instanceof Slice
}
pragma [noinline]
private predicate sequence_subscript_slice(ControlFlowNode obj, SubscriptNode sub) {
sub.isLoad() and
sub.getValue() = obj and
sub.getNode().getIndex() instanceof Slice
}
/** A taint kind representing a mapping of objects to kinds.
* Typically a dict, but can include other mappings.
*/
@@ -262,20 +259,6 @@ class DictKind extends CollectionKind {
result = valueKind
}
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
result = valueKind and
tonode.(SubscriptNode).getValue() = fromnode and tonode.isLoad()
or
result = valueKind and
tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode
or
result = this and TaintFlowImplementation::copyCall(fromnode, tonode)
or
result = this and
tonode.(CallNode).getFunction().refersTo(theDictType()) and
tonode.(CallNode).getArg(0) = fromnode
}
override TaintKind getTaintOfMethodResult(string name) {
name = "get" and result = valueKind
or
@@ -291,6 +274,24 @@ class DictKind extends CollectionKind {
}
module DictKind {
predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
TaintFlowImplementation::copyCall(fromnode, tonode)
or
tonode.(CallNode).getFunction().refersTo(theDictType()) and
tonode.(CallNode).getArg(0) = fromnode
}
predicate valueFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
tonode.(SubscriptNode).getValue() = fromnode and tonode.isLoad()
or
tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode
}
}
/** A type of sanitizer of untrusted data.
* Examples include sanitizers for http responses, for DB access or for shell commands.
* Usually a sanitizer can only sanitize data for one particular use.
@@ -318,6 +319,18 @@ abstract class Sanitizer extends string {
}
/** Hold if `sanitizer` is valid. A sanitizer is valid if there is
* a `TaintTracking::Configuration` that declares `sanitizer` or
* there are no `TaintTracking::Configuration`s.
*/
private predicate valid_sanitizer(Sanitizer sanitizer) {
not exists(TaintTracking::Configuration c)
or
exists(DataFlow::Configuration c | c.isSanitizer(sanitizer))
or
exists(TaintTracking::Configuration c | c.isSanitizer(sanitizer))
}
/** DEPRECATED -- Use DataFlowExtension instead.
* An extension to taint-flow. For adding library or framework specific flows.
* Examples include flow from a request to untrusted part of that request or
@@ -584,12 +597,19 @@ private newtype TTaintedNode =
n.(TaintSource).isSourceOf(kind, context)
)
or
exists(DataFlow::Configuration config, TaintKind kind |
taint = TaintFlowImplementation::TTrackedTaint(kind) and
config.isSource(n) and context.getDepth() = 0 and
kind instanceof GenericFlowType
)
or
TaintFlowImplementation::step(_, taint, context, n) and
exists(TaintKind kind |
kind = taint.(TaintFlowImplementation::TrackedTaint).getKind()
or
kind = taint.(TaintFlowImplementation::TrackedAttribute).getKind(_) |
not exists(Sanitizer sanitizer |
valid_sanitizer(sanitizer) and
sanitizer.sanitizingNode(kind, n)
)
)
@@ -839,26 +859,37 @@ library module TaintFlowImplementation {
or
call_taint_step(fromnode, totaint, tocontext, tonode)
or
fromnode.getNode().(DataFlowNode).getASuccessorNode() = tonode and
fromnode.getContext() = tocontext and
totaint = fromnode.getTrackedValue()
or
exists(CallNode call |
fromnode.getNode().(DataFlowNode).getAReturnSuccessorNode(call) = tonode and
fromnode.getContext() = tocontext.getCallee(call) and
exists(DataFlowNode fromnodenode |
fromnodenode = fromnode.getNode() and
(
not exists(TaintTracking::Configuration c)
or
exists(DataFlow::Configuration c | c.isExtension(fromnodenode))
or
exists(TaintTracking::Configuration c | c.isExtension(fromnodenode))
)
|
fromnodenode.getASuccessorNode() = tonode and
fromnode.getContext() = tocontext and
totaint = fromnode.getTrackedValue()
)
or
exists(CallNode call |
fromnode.getNode().(DataFlowNode).getACalleeSuccessorNode(call) = tonode and
fromnode.getContext().getCallee(call) = tocontext and
totaint = fromnode.getTrackedValue()
)
or
exists(TaintKind tokind |
fromnode.getNode().(DataFlowNode).getASuccessorNode(fromnode.getTaintKind(), tokind) = tonode and
totaint = fromnode.getTrackedValue().toKind(tokind) and
tocontext = fromnode.getContext()
or
exists(CallNode call |
fromnodenode.getAReturnSuccessorNode(call) = tonode and
fromnode.getContext() = tocontext.getCallee(call) and
totaint = fromnode.getTrackedValue()
)
or
exists(CallNode call |
fromnodenode.getACalleeSuccessorNode(call) = tonode and
fromnode.getContext().getCallee(call) = tocontext and
totaint = fromnode.getTrackedValue()
)
or
exists(TaintKind tokind |
fromnodenode.getASuccessorNode(fromnode.getTaintKind(), tokind) = tonode and
totaint = fromnode.getTrackedValue().toKind(tokind) and
tocontext = fromnode.getContext()
)
)
or
exists(TaintKind tokind |
@@ -867,6 +898,22 @@ library module TaintFlowImplementation {
tocontext = fromnode.getContext()
)
or
exists(SequenceKind fromkind |
fromkind = fromnode.getTaintKind() and
tocontext = fromnode.getContext() |
totaint = fromnode.getTrackedValue() and SequenceKind::flowStep(fromnode.getNode(), tonode)
or
totaint = fromnode.getTrackedValue().toKind(fromkind.getItem()) and SequenceKind::itemFlowStep(fromnode.getNode(), tonode)
)
or
exists(DictKind fromkind |
fromkind = fromnode.getTaintKind() and
tocontext = fromnode.getContext() |
totaint = fromnode.getTrackedValue() and DictKind::flowStep(fromnode.getNode(), tonode)
or
totaint = fromnode.getTrackedValue().toKind(fromkind.getValue()) and DictKind::valueFlowStep(fromnode.getNode(), tonode)
)
or
exists(TaintFlow flow, TaintKind tokind |
flow.additionalFlowStep(fromnode.getNode(), fromnode.getTaintKind(), tonode, tokind) and
totaint = fromnode.getTrackedValue().toKind(tokind) and
@@ -1038,8 +1085,18 @@ library module TaintFlowImplementation {
prev.(DataFlowVariable).getASuccessorVariable() = var
)
or
origin.getNode().(DataFlowNode).getASuccessorVariable() = var and
context = origin.getContext()
exists(DataFlowNode originnode |
originnode = origin.getNode() and
(
not exists(TaintTracking::Configuration c)
or
exists(DataFlow::Configuration c | c.isExtension(originnode))
or
exists(TaintTracking::Configuration c | c.isExtension(originnode))
) and
originnode.getASuccessorVariable() = var and
context = origin.getContext()
)
or
exists(TrackedTaint taint, EssaVariable prev |
tainted_var(prev, context, origin) and
@@ -1062,6 +1119,7 @@ library module TaintFlowImplementation {
exists(TaintKind kind |
kind = origin.getTaintKind() and
not exists(Sanitizer san |
valid_sanitizer(san) |
san.sanitizingDefinition(kind, def)
or
san.sanitizingNode(kind, def.(EssaNodeDefinition).getDefiningNode())
@@ -1184,6 +1242,7 @@ library module TaintFlowImplementation {
exists(TaintKind kind |
kind = origin.getTaintKind() |
not exists(FunctionObject callee, Sanitizer sanitizer |
valid_sanitizer(sanitizer) and
callee.getACall() = call.getCall() and
sanitizer.sanitizingCall(kind, callee)
)
@@ -1197,11 +1256,12 @@ library module TaintFlowImplementation {
var = test.getInput() and
tainted_var(var, context, origin) and
not exists(Sanitizer sanitizer |
valid_sanitizer(sanitizer) and
sanitizer.sanitizingEdge(kind, test)
)
|
not Filters::isinstance(test.getTest(), _, var.getSourceVariable().getAUse()) and
not test.getTest() = var.getSourceVariable().getAUse()
not boolean_filter(test.getTest(), var.getSourceVariable().getAUse())
or
exists(ControlFlowNode c, ClassObject cls |
Filters::isinstance(test.getTest(), c, var.getSourceVariable().getAUse())
@@ -1212,10 +1272,42 @@ library module TaintFlowImplementation {
test.getSense() = false and not kind.getClass().getAnImproperSuperType() = cls
)
or
test.getTest() = var.getSourceVariable().getAUse() and kind.booleanValue() = test.getSense()
test.getSense() = test_evaluates(test.getTest(), var.getSourceVariable().getAUse(), kind)
)
}
/** Gets the operand of a unary `not` expression. */
private ControlFlowNode not_operand(ControlFlowNode expr) {
expr.(UnaryExprNode).getNode().getOp() instanceof Not and
result = expr.(UnaryExprNode).getOperand()
}
/** Holds if `test` is the test in a branch and `use` is that test
* with all the `not` prefixes removed.
*/
private predicate boolean_filter(ControlFlowNode test, ControlFlowNode use) {
any(PyEdgeRefinement ref).getTest() = test and
(
use = test
or
exists(ControlFlowNode notuse |
boolean_filter(test, notuse) and
use = not_operand(notuse)
)
)
}
/** Gets the boolean value that `test` evaluates to when `use` is tainted with `kind`
* and `test` and `use` are part of a test in a branch.
*/
private boolean test_evaluates(ControlFlowNode test, ControlFlowNode use, TaintKind kind) {
boolean_filter(_, use) and
kind.taints(use) and
test = use and result = kind.booleanValue()
or
result = test_evaluates(not_operand(test), use, kind).booleanNot()
}
pragma [noinline]
predicate tainted_argument(ArgumentRefinement def, CallContext context, TaintedNode origin) {
tainted_var(def.getInput(), context, origin)
@@ -1246,6 +1338,7 @@ library module TaintFlowImplementation {
var = uniphi.getInput() and
tainted_var(var, context, origin) and
not exists(Sanitizer sanitizer |
valid_sanitizer(sanitizer) and
sanitizer.sanitizingSingleEdge(kind, uniphi)
)
)
@@ -1438,6 +1531,109 @@ class CallContext extends TCallContext {
}
/** Data flow module providing an interface compatible with
* the other language implementations.
*/
module DataFlow {
class FlowType = TaintKind;
/** Generic taint kind, source and sink classes for convenience and
* compatibility with other language libraries
*/
class Node = ControlFlowNode;
class PathNode = TaintedNode;
class Extension = DataFlowExtension::DataFlowNode;
abstract class Configuration extends string {
bindingset[this]
Configuration() { this = this }
abstract predicate isSource(Node source);
abstract predicate isSink(Node sink);
predicate isSanitizer(Sanitizer sanitizer) { none() }
predicate isExtension(Extension extension) { none() }
predicate hasFlowPath(PathNode source, PathNode sink) {
this.isSource(source.getNode()) and
this.isSink(sink.getNode()) and
source.getTaintKind() instanceof GenericFlowType and
sink.getTaintKind() instanceof GenericFlowType
}
predicate hasFlow(Node source, Node sink) {
exists(PathNode psource, PathNode psink |
psource.getNode() = source and
psink.getNode() = sink and
this.isSource(source) and
this.isSink(sink) and
this.hasFlowPath(psource, psink)
)
}
}
}
private class GenericFlowType extends DataFlow::FlowType {
GenericFlowType() {
this = "Generic taint kind" and
exists(DataFlow::Configuration c)
}
}
module TaintTracking {
class Source = TaintSource;
class Sink = TaintSink;
class PathSource = TaintedPathSource;
class PathSink = TaintedPathSink;
class Extension = DataFlowExtension::DataFlowNode;
abstract class Configuration extends string {
bindingset[this]
Configuration() { this = this }
abstract predicate isSource(Source source);
abstract predicate isSink(Sink sink);
predicate isSanitizer(Sanitizer sanitizer) { none() }
predicate isExtension(Extension extension) { none() }
predicate hasFlowPath(PathSource source, PathSink sink) {
this.isSource(source.getNode()) and
this.isSink(sink.getNode()) and
source.flowsTo(sink)
}
predicate hasFlow(Source source, Sink sink) {
this.isSource(source) and
this.isSink(sink) and
source.flowsToSink(sink)
}
}
}
pragma [noinline]
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {
dictnode.(DictNode).getAValue() = itemnode

View File

@@ -83,7 +83,7 @@ class ShellCommand extends TaintSink {
or
exists(CallNode call |
call.getAnArg() = this and
call.getFunction().refersTo(any(ModuleObject commands | commands.getName() = "commands"))
call.getFunction().refersTo(ModuleObject::named("commands"))
)
}

View File

@@ -91,7 +91,7 @@ private predicate json_subscript_taint(SubscriptNode sub, ControlFlowNode obj, E
private predicate json_load(ControlFlowNode fromnode, CallNode tonode) {
exists(FunctionObject json_loads |
any(ModuleObject json | json.getName() = "json").attr("loads") = json_loads and
ModuleObject::named("json").attr("loads") = json_loads and
json_loads.getACall() = tonode and tonode.getArg(0) = fromnode
)
}

View File

@@ -3,6 +3,10 @@
*
* This should be considered an advance feature. Modifying the points-to analysis
* can cause queries to give strange and misleading results, if not done with care.
*
* WARNING:
* This module interacts with the internals of points-to analysis and
* the classes here are more likely to change than the rest of the library.
*/
import python
@@ -34,6 +38,18 @@ abstract class CustomPointsToOriginFact extends CustomPointsToFact {
}
/* Custom points-to fact with inferred class */
abstract class CustomPointsToObjectFact extends CustomPointsToFact {
abstract predicate pointsTo(Object value);
override predicate pointsTo(Context context, Object value, ClassObject cls, ControlFlowNode origin) {
this.pointsTo(value) and cls = simple_types(value) and origin = this and context.appliesTo(this)
}
}
/** INTERNAL -- Do not use */
abstract class CustomPointsToAttribute extends Object {

View File

@@ -9,7 +9,7 @@ ModuleObject theBottleModule() {
/** The bottle.Bottle class */
ClassObject theBottleClass() {
result = ModuleObject::named("bottle").attr("Bottle")
result = theBottleModule().attr("Bottle")
}
/** Holds if `route` is routed to `func`

View File

@@ -12,7 +12,7 @@ class DjangoDbCursor extends DbCursor {
}
private Object theDjangoConnectionObject() {
any(ModuleObject m | m.getName() = "django.db").attr("connection") = result
ModuleObject::named("django.db").attr("connection") = result
}
/** A kind of taint source representing sources of django cursor objects.
@@ -38,7 +38,7 @@ class DjangoDbCursorSource extends DbConnectionSource {
ClassObject theDjangoRawSqlClass() {
result = any(ModuleObject m | m.getName() = "django.db.models.expressions").attr("RawSQL")
result = ModuleObject::named("django.db.models.expressions").attr("RawSQL")
}
/**

View File

@@ -8,7 +8,7 @@ import semmle.python.web.Http
class DjangoModel extends ClassObject {
DjangoModel() {
any(ModuleObject m | m.getName() = "django.db.models").attr("Model") = this.getAnImproperSuperType()
ModuleObject::named("django.db.models").attr("Model") = this.getAnImproperSuperType()
}
}

View File

@@ -82,7 +82,7 @@ private class DjangoFunctionBasedViewRequestArgument extends DjangoRequestSource
private class DjangoView extends ClassObject {
DjangoView() {
any(ModuleObject m | m.getName() = "django.views.generic").attr("View") = this.getAnImproperSuperType()
ModuleObject::named("django.views.generic").attr("View") = this.getAnImproperSuperType()
}
}
@@ -109,7 +109,7 @@ class DjangoClassBasedViewRequestArgument extends DjangoRequestSource {
/* Function based views */
predicate url_dispatch(CallNode call, ControlFlowNode regex, FunctionObject view) {
exists(FunctionObject url |
any(ModuleObject m | m.getName() = "django.conf.urls").attr("url") = url and
ModuleObject::named("django.conf.urls").attr("url") = url and
url.getArgumentForCall(call, 0) = regex and
url.getArgumentForCall(call, 1).refersTo(view)
)

View File

@@ -17,7 +17,7 @@ class DjangoResponse extends TaintKind {
}
private ClassObject theDjangoHttpResponseClass() {
result = any(ModuleObject m | m.getName() = "django.http.response").attr("HttpResponse") and
result = ModuleObject::named("django.http.response").attr("HttpResponse") and
not result = theDjangoHttpRedirectClass()
}
@@ -44,7 +44,7 @@ class DjangoResponseWrite extends TaintSink {
DjangoResponseWrite() {
exists(AttrNode meth, CallNode call |
call.getFunction() = meth and
any(DjangoResponse repsonse).taints(meth.getObject("write")) and
any(DjangoResponse response).taints(meth.getObject("write")) and
this = call.getArg(0)
)
}

View File

@@ -1,9 +1,9 @@
import python
FunctionObject redirect() {
result = any(ModuleObject m | m.getName() = "django.shortcuts").attr("redirect")
result = ModuleObject::named("django.shortcuts").attr("redirect")
}
ClassObject theDjangoHttpRedirectClass() {
result = any(ModuleObject m | m.getName() = "django.http.response").attr("HttpResponseRedirectBase")
result = ModuleObject::named("django.http.response").attr("HttpResponseRedirectBase")
}

View File

@@ -4,7 +4,7 @@ import semmle.python.web.Http
/** The falcon API class */
ClassObject theFalconAPIClass() {
result = ModuleObject::named("falcon").getAttribute("API")
result = ModuleObject::named("falcon").attr("API")
}

View File

@@ -3,7 +3,7 @@ import semmle.python.web.Http
/** The flask module */
ModuleObject theFlaskModule() {
result = any(ModuleObject m | m.getName() = "flask")
result = ModuleObject::named("flask")
}
/** The flask app class */
@@ -13,7 +13,7 @@ ClassObject theFlaskClass() {
/** The flask MethodView class */
ClassObject theFlaskMethodViewClass() {
result = any(ModuleObject m | m.getName() = "flask.views").attr("MethodView")
result = ModuleObject::named("flask.views").attr("MethodView")
}
ClassObject theFlaskReponseClass() {

View File

@@ -12,7 +12,7 @@ class PyramidRequest extends BaseWebobRequest {
}
override ClassObject getClass() {
result = any(ModuleObject m | m.getName() = "pyramid.request").attr("Request")
result = ModuleObject::named("pyramid.request").attr("Request")
}
}

View File

@@ -3,7 +3,7 @@ import python
import semmle.python.security.TaintTracking
private ClassObject theTornadoRequestHandlerClass() {
result = any(ModuleObject m | m.getName() = "tornado.web").attr("RequestHandler")
result = ModuleObject::named("tornado.web").attr("RequestHandler")
}
ClassObject aTornadoRequestHandlerClass() {

View File

@@ -3,7 +3,7 @@ import python
import semmle.python.security.TaintTracking
private ClassObject theTurboGearsControllerClass() {
result = ModuleObject::named("tg").getAttribute("TGController")
result = ModuleObject::named("tg").attr("TGController")
}
@@ -23,7 +23,7 @@ class TurboGearsControllerMethod extends Function {
(
decorator.(CallNode).getFunction().(NameNode).getId() = "expose"
or
decorator.refersTo(_, ModuleObject::named("tg").getAttribute("expose"), _)
decorator.refersTo(_, ModuleObject::named("tg").attr("expose"), _)
)
}

View File

@@ -3,11 +3,11 @@ import python
import semmle.python.security.TaintTracking
private ClassObject theTwistedHttpRequestClass() {
result = any(ModuleObject m | m.getName() = "twisted.web.http").attr("Request")
result = ModuleObject::named("twisted.web.http").attr("Request")
}
private ClassObject theTwistedHttpResourceClass() {
result = any(ModuleObject m | m.getName() = "twisted.web.resource").attr("Resource")
result = ModuleObject::named("twisted.web.resource").attr("Resource")
}
ClassObject aTwistedRequestHandlerClass() {

View File

@@ -45,7 +45,7 @@ class WebobRequest extends BaseWebobRequest {
}
override ClassObject getClass() {
result = any(ModuleObject m | m.getName() = "webob.request").attr("Request")
result = ModuleObject::named("webob.request").attr("Request")
}
}