Python: Basic support for falcon framework; routing and requests.

This commit is contained in:
Mark Shannon
2019-02-07 14:46:11 +00:00
parent 742c1d0fa7
commit 6a48420191
11 changed files with 177 additions and 9 deletions

View File

@@ -96,3 +96,23 @@ private predicate json_load(ControlFlowNode fromnode, CallNode tonode) {
)
}
/** A kind of "taint", representing am open file-like object from an external source. */
class ExternalFileObject extends TaintKind {
ExternalFileObject() {
this = "file[" + any(ExternalStringKind key) + "]"
}
/** Gets the taint kind for item in this sequence */
TaintKind getValue() {
this = "file[" + result + "]"
}
override TaintKind getTaintOfMethodResult(string name) {
name = "read" and result = this.getValue()
}
}

View File

@@ -5,3 +5,4 @@ import semmle.python.web.pyramid.Request
import semmle.python.web.twisted.Request
import semmle.python.web.bottle.Request
import semmle.python.web.turbogears.Request
import semmle.python.web.falcon.Request

View File

@@ -0,0 +1,68 @@
import python
import semmle.python.web.Http
/** The falcon API class */
ClassObject theFalconAPIClass() {
result = ModuleObject::named("falcon").getAttribute("API")
}
/** Holds if `route` is routed to `resource`
*/
private predicate api_route(CallNode route_call, ControlFlowNode route, ClassObject resource) {
route_call.getFunction().(AttrNode).getObject("add_route").refersTo(_, theFalconAPIClass(), _) and
route_call.getArg(0) = route and
route_call.getArg(1).refersTo(_, resource, _)
}
class FalconRoute extends ControlFlowNode {
FalconRoute() {
api_route(this, _, _)
}
string getUrl() {
exists(StrConst url |
api_route(this, url.getAFlowNode(), _) and
result = url.getText()
)
}
ClassObject getResourceClass() {
api_route(this, _, result)
}
FalconHandlerFunction getHandlerFunction() {
result = this.getResourceClass().lookupAttribute(_).(FunctionObject).getFunction()
}
FalconHandlerFunction getHandlerFunction(string method) {
result = this.getResourceClass().lookupAttribute("on_" + method).(FunctionObject).getFunction()
}
}
class FalconHandlerFunction extends Function {
string method;
FalconHandlerFunction() {
exists(ClassObject resource |
resource.lookupAttribute("on_" + method).(FunctionObject).getFunction() = this
)
}
string getMethod() {
result = method.toUpperCase()
}
Parameter getRequest() {
result = this.getArg(1)
}
Parameter getResponse() {
result = this.getArg(2)
}
}

View File

@@ -0,0 +1,55 @@
import python
import semmle.python.security.TaintTracking
import semmle.python.web.Http
import semmle.python.web.falcon.General
import semmle.python.security.strings.External
/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */
class FalconRequest extends TaintKind {
FalconRequest() {
this = "falcon.request"
}
override TaintKind getTaintOfAttribute(string name) {
// name = "env" and result instanceof WsgiEnvironment
result instanceof ExternalStringKind and
(
name = "uri" or name = "url" or
name = "forwarded_uri" or
name = "relative_uri" or
name = "query_string"
)
or
result instanceof ExternalStringDictKind and
(
name = "cookies" or name = "params"
)
or
name = "stream" and result instanceof ExternalFileObject
}
override TaintKind getTaintOfMethodResult(string name) {
name = "get_param" and result instanceof ExternalStringKind
or
name = "get_param_as_json" and result instanceof ExternalJsonKind
or
name = "get_param_as_list" and result instanceof ExternalStringSequenceKind
}
}
class FalconRequestParameter extends TaintSource {
FalconRequestParameter() {
exists(FalconHandlerFunction f |
f.getRequest() = this.(ControlFlowNode).getNode()
)
}
override predicate isSourceOf(TaintKind k) {
k instanceof FalconRequest
}
}