Python: Add wsgi.environment as a kind of taint, and add suuport for env attribute of falcon request objects.

This commit is contained in:
Mark Shannon
2019-02-28 11:19:50 +00:00
parent 9170d85155
commit 1444b3976c
8 changed files with 69 additions and 19 deletions

View File

@@ -167,6 +167,7 @@ abstract class CollectionKind extends TaintKind {
/* Prevent any collection kinds more than 2 deep */
not this.charAt(2) = "[" and not this.charAt(2) = "{"
}
}
/** A taint kind representing a flat collections of kinds.
@@ -193,7 +194,7 @@ class SequenceKind extends CollectionKind {
tonode.(BinaryExprNode).getAnOperand() = fromnode
)
or
result = this and copy_call(fromnode, tonode)
result = this and TaintFlowImplementation::copyCall(fromnode, tonode)
or
exists(BinaryExprNode mod |
mod = tonode and
@@ -236,20 +237,6 @@ private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) {
)
}
/* A call that returns a copy (or similar) of the argument */
private predicate copy_call(ControlFlowNode fromnode, CallNode tonode) {
tonode.getFunction().(AttrNode).getObject("copy") = fromnode
or
exists(ModuleObject copy, string name |
name = "copy" or name = "deepcopy" |
copy.attr(name).(FunctionObject).getACall() = tonode and
tonode.getArg(0) = fromnode
)
or
tonode.getFunction().refersTo(Object::builtin("reversed")) and
tonode.getArg(0) = fromnode
}
/** A taint kind representing a mapping of objects to kinds.
* Typically a dict, but can include other mappings.
*/
@@ -272,7 +259,7 @@ class DictKind extends CollectionKind {
result = valueKind and
tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode
or
result = this and copy_call(fromnode, tonode)
result = this and TaintFlowImplementation::copyCall(fromnode, tonode)
or
result = this and
tonode.(CallNode).getFunction().refersTo(theDictType()) and
@@ -1263,6 +1250,20 @@ library module TaintFlowImplementation {
context = fromnode.getContext()
}
/* A call that returns a copy (or similar) of the argument */
predicate copyCall(ControlFlowNode fromnode, CallNode tonode) {
tonode.getFunction().(AttrNode).getObject("copy") = fromnode
or
exists(ModuleObject copy, string name |
name = "copy" or name = "deepcopy" |
copy.attr(name).(FunctionObject).getACall() = tonode and
tonode.getArg(0) = fromnode
)
or
tonode.getFunction().refersTo(Object::builtin("reversed")) and
tonode.getArg(0) = fromnode
}
}
/* Helper predicate for tainted_with */

View File

@@ -96,7 +96,7 @@ private predicate json_load(ControlFlowNode fromnode, CallNode tonode) {
)
}
/** A kind of "taint", representing am open file-like object from an external source. */
/** A kind of "taint", representing an open file-like object from an external source. */
class ExternalFileObject extends TaintKind {
ExternalFileObject() {
@@ -104,7 +104,7 @@ class ExternalFileObject extends TaintKind {
}
/** Gets the taint kind for item in this sequence */
/** Gets the taint kind for the contents of this file */
TaintKind getValue() {
this = "file[" + result + "]"
}

View File

@@ -23,3 +23,37 @@ string httpVerb() {
string httpVerbLower() {
result = httpVerb().toLowerCase()
}
/** Taint kind representing the WSGI environment.
* As specified in PEP 3333. https://www.python.org/dev/peps/pep-3333/#environ-variables
*/
class WsgiEnvironment extends TaintKind {
WsgiEnvironment() { this = "wsgi.environment" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
result = this and TaintFlowImplementation::copyCall(fromnode, tonode)
or
result = this and
tonode.(CallNode).getFunction().refersTo(theDictType()) and
tonode.(CallNode).getArg(0) = fromnode
or
exists(StringObject key, string text |
tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode and
tonode.(CallNode).getArg(0).refersTo(key)
or
tonode.(SubscriptNode).getValue() = fromnode and tonode.isLoad() and
tonode.(SubscriptNode).getIndex().refersTo(key)
|
text = key.getText() and result instanceof ExternalStringKind and
(
text = "QUERY_STRING" or
text = "PATH_INFO" or
text.prefix(5) = "HTTP_"
)
)
}
}

View File

@@ -13,7 +13,8 @@ class FalconRequest extends TaintKind {
}
override TaintKind getTaintOfAttribute(string name) {
// name = "env" and result instanceof WsgiEnvironment
name = "env" and result instanceof WsgiEnvironment
or
result instanceof ExternalStringKind and
(
name = "uri" or name = "url" or