Python: Model HTTP responses in tornado

This is quite a simpel model, but ends up matching what we were able to do with
points-to.

I think this modeling excercise really shows that we need a bit of a different
way to model HTTP responses... but I'm not going to try to fix that in this PR.
This commit is contained in:
Rasmus Wriedt Larsen
2021-01-21 13:26:31 +01:00
parent ac77a8b8a8
commit b55817a5b2
4 changed files with 58 additions and 22 deletions

View File

@@ -216,6 +216,17 @@ private module Tornado {
/** Gets a reference to one of the methods `get_arguments`, `get_body_arguments`, `get_query_arguments`. */
DataFlow::Node argumentsMethod() { result = argumentsMethod(DataFlow::TypeTracker::end()) }
/** Gets a reference to the `write` method. */
private DataFlow::Node writeMethod(DataFlow::TypeTracker t) {
t.startInAttr("write") and
result = instance()
or
exists(DataFlow::TypeTracker t2 | result = writeMethod(t2).track(t2, t))
}
/** Gets a reference to the `write` method. */
DataFlow::Node writeMethod() { result = writeMethod(DataFlow::TypeTracker::end()) }
private class AdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
// Method access
@@ -540,4 +551,29 @@ private module Tornado {
not result = this.getArg(0)
}
}
// ---------------------------------------------------------------------------
// Response modeling
// ---------------------------------------------------------------------------
/**
* A call to `tornado.web.RequestHandler.write` method.
*
* See https://www.tornadoweb.org/en/stable/web.html?highlight=write#tornado.web.RequestHandler.write
*/
private class TornadoRequestHandlerWriteCall extends HTTP::Server::HttpResponse::Range,
DataFlow::CfgNode {
override CallNode node;
TornadoRequestHandlerWriteCall() {
node.getFunction() = tornado::web::RequestHandler::writeMethod().asCfgNode()
}
override DataFlow::Node getBody() {
result.asCfgNode() in [node.getArg(0), node.getArgByName("chunk")]
}
override string getMimetypeDefault() { result = "text/html" }
override DataFlow::Node getMimetypeOrContentTypeArg() { none() }
}
}