refactor definesExplicitly to use DataFlow::Node

This commit is contained in:
Erik Krogh Kristensen
2022-03-30 12:56:22 +02:00
committed by erik-krogh
parent ce0175a046
commit 19e808186d
7 changed files with 32 additions and 23 deletions

View File

@@ -737,9 +737,9 @@ module Express {
*/
private DataFlow::SourceNode getAHeaderSource() { result.flowsTo(this.getArgument(0)) }
override predicate definesExplicitly(string headerName, Expr headerValue) {
override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) {
exists(string header |
this.getAHeaderSource().hasPropertyWrite(header, DataFlow::valueNode(headerValue)) and
this.getAHeaderSource().hasPropertyWrite(header, headerValue) and
headerName = header.toLowerCase()
)
}

View File

@@ -392,9 +392,9 @@ module Fastify {
*/
private DataFlow::SourceNode getAHeaderSource() { result.flowsTo(this.getArgument(0)) }
override predicate definesExplicitly(string headerName, Expr headerValue) {
override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) {
exists(string header |
this.getAHeaderSource().hasPropertyWrite(header, headerValue.flow()) and
this.getAHeaderSource().hasPropertyWrite(header, headerValue) and
headerName = header.toLowerCase()
)
}

View File

@@ -56,19 +56,25 @@ module HTTP {
* An expression that sets HTTP response headers explicitly.
*/
abstract class ExplicitHeaderDefinition extends HeaderDefinition {
override string getAHeaderName() { this.definesExplicitly(result, _) }
override string getAHeaderName() { this.definesHeaderValue(result, _) }
override predicate defines(string headerName, string headerValue) {
exists(Expr e |
this.definesExplicitly(headerName, e) and
exists(DataFlow::Node e |
this.definesHeaderValue(headerName, e) and
headerValue = e.getStringValue()
)
}
/**
* DEPRECATED: use `definesHeaderValue` instead.
* Holds if the header with (lower-case) name `headerName` is set to the value of `headerValue`.
*/
abstract predicate definesExplicitly(string headerName, Expr headerValue); // TODO: DataFlow::Node.
deprecated predicate definesExplicitly(string headerName, Expr headerValue) {
this.definesHeaderValue(headerName, headerValue.flow())
}
/** Holds if the header with (lower-case) name `headerName` is set to the value of `headerValue`. */
abstract predicate definesHeaderValue(string headerName, DataFlow::Node headerValue);
/**
* DEPRECATED: Use `getNameNode()` instead.
@@ -128,20 +134,21 @@ module HTTP {
* An expression that sets a cookie in an HTTP response.
*/
abstract class CookieDefinition extends Expr {
// TODO: DataFlow::Node
/**
* Gets the argument, if any, specifying the raw cookie header.
*/
Expr getHeaderArgument() { none() }
Expr getHeaderArgument() { none() } // TODO: DataFlow::Node
/**
* Gets the argument, if any, specifying the cookie name.
*/
Expr getNameArgument() { none() }
Expr getNameArgument() { none() } // TODO: DataFlow::Node
/**
* Gets the argument, if any, specifying the cookie value.
*/
Expr getValueArgument() { none() }
Expr getValueArgument() { none() } // TODO: DataFlow::Node
/** Gets the route handler that sets this cookie. */
abstract RouteHandler getRouteHandler();
@@ -159,7 +166,7 @@ module HTTP {
}
override Expr getHeaderArgument() {
header.(ExplicitHeaderDefinition).definesExplicitly("set-cookie", result)
header.(ExplicitHeaderDefinition).definesHeaderValue("set-cookie", result.flow())
}
override RouteHandler getRouteHandler() { result = header.getRouteHandler() }
@@ -384,9 +391,9 @@ module HTTP {
*/
abstract class StandardHeaderDefinition extends ExplicitHeaderDefinition,
DataFlow::MethodCallNode {
override predicate definesExplicitly(string headerName, Expr headerValue) {
override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) {
headerName = this.getNameNode().getStringValue().toLowerCase() and
headerValue = this.getArgument(1).asExpr()
headerValue = this.getArgument(1)
}
override DataFlow::Node getNameNode() { result = this.getArgument(0) }

View File

@@ -280,11 +280,11 @@ module NodeJSLib {
this.getNumArgument() >= 1
}
override predicate definesExplicitly(string headerName, Expr headerValue) {
override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) {
this.getNumArgument() > 1 and
exists(DataFlow::SourceNode headers, string header |
headers.flowsTo(this.getLastArgument()) and
headers.hasPropertyWrite(header, DataFlow::valueNode(headerValue)) and
headers.hasPropertyWrite(header, headerValue) and
headerName = header.toLowerCase()
)
}

View File

@@ -46,12 +46,12 @@ module CorsMisconfigurationForCredentials {
CorsOriginHeaderWithAssociatedCredentialHeader() {
exists(
HTTP::RouteHandler routeHandler, HTTP::ExplicitHeaderDefinition origin,
Expr credentialsValue
DataFlow::Node credentialsValue
|
routeHandler.getAResponseHeader(_) = origin and
routeHandler.getAResponseHeader(_) = credentials and
origin.definesExplicitly("access-control-allow-origin", this.asExpr()) and
credentials.definesExplicitly("access-control-allow-credentials", credentialsValue)
origin.definesHeaderValue("access-control-allow-origin", this) and
credentials.definesHeaderValue("access-control-allow-credentials", credentialsValue)
|
credentialsValue.mayHaveBooleanValue(true) or
credentialsValue.mayHaveStringValue("true")

View File

@@ -41,9 +41,9 @@ module ServerSideUrlRedirect {
* A definition of the HTTP "Location" header, considered as a sink for
* `Configuration`.
*/
class LocationHeaderSink extends Sink, DataFlow::ValueNode {
class LocationHeaderSink extends Sink {
LocationHeaderSink() {
any(HTTP::ExplicitHeaderDefinition def).definesExplicitly("location", astNode)
any(HTTP::ExplicitHeaderDefinition def).definesHeaderValue("location", this)
}
}

View File

@@ -1,5 +1,7 @@
import javascript
query predicate test_HeaderDefinition_getNameExpr(HTTP::ExplicitHeaderDefinition hd, Expr res) {
hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getNameExpr()
query predicate test_HeaderDefinition_getNameExpr(
HTTP::ExplicitHeaderDefinition hd, DataFlow::Node res
) {
hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getNameNode()
}