Python: Model mimetype instead of content-type for HTTP Response

Since that's really what we're after (at least for now)
This commit is contained in:
Rasmus Wriedt Larsen
2020-10-22 14:32:19 +02:00
parent 81a42b73a8
commit 082e35c2c7
6 changed files with 43 additions and 50 deletions

View File

@@ -26,7 +26,7 @@ class ReflectedXssConfiguration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) {
exists(HTTP::Server::HttpResponse response |
response.getContentType().toLowerCase().matches("text/html%") and
response.getMimetype().toLowerCase() = "text/html" and
sink = response.getBody()
)
}

View File

@@ -237,8 +237,8 @@ module HTTP {
/** Gets the data-flow node that specifies the body of this HTTP response. */
DataFlow::Node getBody() { result = range.getBody() }
/** Gets the content-type of this HTTP response, if it can be statically determined. */
string getContentType() { result = range.getContentType() }
/** Gets the mimetype of this HTTP response, if it can be statically determined. */
string getMimetype() { result = range.getMimetype() }
}
/** Provides a class for modeling new HTTP response APIs. */
@@ -256,21 +256,21 @@ module HTTP {
/** Gets the data-flow node that specifies the body of this HTTP response. */
abstract DataFlow::Node getBody();
/** Gets the data-flow node that specifies the content-type of this HTTP response, if any. */
abstract DataFlow::Node getContentTypeArg();
/** Gets the data-flow node that specifies the content-type/mimetype of this HTTP response, if any. */
abstract DataFlow::Node getMimetypeOrContentTypeArg();
/** Gets the default content-type that should be used if `getContentTypeArg` has no results. */
abstract string getContentTypeDefault();
/** Gets the default mimetype that should be used if `getMimetypeOrContentTypeArg` has no results. */
abstract string getMimetypeDefault();
/** Gets the content-type of this HTTP response, if it can be statically determined. */
string getContentType() {
/** Gets the mimetype of this HTTP response, if it can be statically determined. */
string getMimetype() {
exists(StrConst str |
DataFlow::localFlow(DataFlow::exprNode(str), this.getContentTypeArg()) and
result = str.getText()
DataFlow::localFlow(DataFlow::exprNode(str), this.getMimetypeOrContentTypeArg()) and
result = str.getText().splitAt(";", 0)
)
or
not exists(this.getContentTypeArg()) and
result = this.getContentTypeDefault()
not exists(this.getMimetypeOrContentTypeArg()) and
result = this.getMimetypeDefault()
}
}
}

View File

@@ -210,27 +210,23 @@ private module FlaskModel {
override DataFlow::Node getBody() { result.asCfgNode() = node.getArg(0) }
override string getContentTypeDefault() { result = "text/html" }
override string getMimetypeDefault() { result = "text/html" }
/** Gets the argument passed to the `mimetype` parameter, if any. */
private DataFlow::Node getMimetypeArg() {
result.asCfgNode() in [node.getArg(3), node.getArgByName("mimetype")]
}
/**
* Gets the actual argument passed to the `content_type` parameter, if any.
* This helper method exists since `getContentTypeArg` is the method exposed by
* `HttpResponse::Range`)
*/
private DataFlow::Node actualContentTypeArg() {
/** Gets the argument passed to the `content_type` parameter, if any. */
private DataFlow::Node getContentTypeArg() {
result.asCfgNode() in [node.getArg(4), node.getArgByName("content_type")]
}
override DataFlow::Node getContentTypeArg() {
result = this.actualContentTypeArg()
override DataFlow::Node getMimetypeOrContentTypeArg() {
result = this.getContentTypeArg()
or
// content_type argument takes priority over mimetype argument
not exists(this.actualContentTypeArg()) and
not exists(this.getContentTypeArg()) and
result = this.getMimetypeArg()
}
}
@@ -464,8 +460,8 @@ private module FlaskModel {
override DataFlow::Node getBody() { result.asCfgNode() = node.getArg(0) }
override string getContentTypeDefault() { result = "text/html" }
override string getMimetypeDefault() { result = "text/html" }
override DataFlow::Node getContentTypeArg() { none() }
override DataFlow::Node getMimetypeOrContentTypeArg() { none() }
}
}