Handle HTTP response writers that are fields

This commit is contained in:
Sauyon Lee
2020-05-13 04:31:07 -07:00
parent 9e5645fa9d
commit 748dd6801e
4 changed files with 22 additions and 9 deletions

View File

@@ -366,8 +366,8 @@ module HTTP {
* extend `HTTP::ResponseWriter` instead.
*/
abstract class Range extends Variable {
/** Gets a data-flow node that represents this response writer. */
DataFlow::Node getANode() { result = this.getARead().getASuccessor*() }
/** Gets a data-flow node that is a use of this response writer. */
abstract DataFlow::Node getANode();
}
}
@@ -391,7 +391,7 @@ module HTTP {
/** Gets a redirect that is sent in this HTTP response. */
Redirect getARedirect() { result.getResponseWriter() = this }
/** Gets a data-flow node that represents this response writer. */
/** Gets a data-flow node that is a use of this response writer. */
DataFlow::Node getANode() { result = self.getANode() }
}

View File

@@ -54,13 +54,21 @@ private module StdlibHttp {
}
}
/** The declaration of a variable which either is or has a field that implements the http.ResponseWriter type */
private class StdlibResponseWriter extends HTTP::ResponseWriter::Range {
StdlibResponseWriter() { this.getType().implements("net/http", "ResponseWriter") }
SsaWithFields v;
StdlibResponseWriter() {
this = v.getBaseVariable().getSourceVariable() and
exists(Type t | t.implements("net/http", "ResponseWriter") | v.getType() = t)
}
override DataFlow::Node getANode() { result = v.similar().getAUse().getASuccessor*() }
/** Gets a header object that corresponds to this HTTP response. */
DataFlow::MethodCallNode getAHeaderObject() {
result.getTarget().hasQualifiedName("net/http", _, "Header") and
this.getARead() = result.getReceiver()
result.getTarget().getName() = "Header" and
this.getANode() = result.getReceiver()
}
}

View File

@@ -6,11 +6,16 @@ import go
private module Macaron {
private class Context extends HTTP::ResponseWriter::Range {
SsaWithFields v;
Context() {
this = v.getBaseVariable().getSourceVariable() and
exists(Method m | m.hasQualifiedName("gopkg.in/macaron.v1", "Context", "Redirect") |
m = this.getType().getMethod("Redirect")
v.getType().getMethod("Redirect") = m
)
}
override DataFlow::Node getANode() { result = v.similar().getAUse().getASuccessor*() }
}
private class RedirectCall extends HTTP::Redirect::Range, DataFlow::MethodCallNode {
@@ -20,6 +25,6 @@ private module Macaron {
override DataFlow::Node getUrl() { result = this.getArgument(0) }
override HTTP::ResponseWriter getResponseWriter() { result.getARead() = this.getReceiver() }
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() }
}
}

View File

@@ -59,7 +59,7 @@ module ReflectedXss {
not htmlTypeSpecified(body) and
(
exists(HTTP::HeaderWrite hw | hw = body.getResponseWriter().getAHeaderWrite() |
hw.definesHeader("content-type", _)
hw.getName().getStringValue().toLowerCase() = "content-type"
)
or
exists(DataFlow::CallNode call | call.getTarget().hasQualifiedName("fmt", "Fprintf") |