mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Python: sinks -> decodings
Query operators that interpret JavaScript are no longer considered sinks. Instead they are considered decodings and the output is the tainted dictionary. The state changes to `DictInput` to reflect that the user now controls a dangerous dictionary. This fixes the spurious result and moves the error reporting to a more logical place.
This commit is contained in:
@@ -123,40 +123,49 @@ private module NoSql {
|
||||
}
|
||||
|
||||
/** The `$where` query operator executes a string as JavaScript. */
|
||||
private class WhereQueryOperator extends API::CallNode, NoSqlQuery::Range {
|
||||
private class WhereQueryOperator extends DataFlow::Node, Decoding::Range {
|
||||
API::Node dictionary;
|
||||
DataFlow::Node query;
|
||||
|
||||
WhereQueryOperator() {
|
||||
this = mongoCollection().getMember(mongoCollectionMethodName()).getACall() and
|
||||
query = this.getParameter(0).getSubscript("$where").asSink()
|
||||
dictionary =
|
||||
mongoCollection().getMember(mongoCollectionMethodName()).getACall().getParameter(0) and
|
||||
query = dictionary.getSubscript("$where").asSink() and
|
||||
this = dictionary.asSink()
|
||||
}
|
||||
|
||||
override DataFlow::Node getQuery() { result = query }
|
||||
override DataFlow::Node getAnInput() { result = query }
|
||||
|
||||
override predicate interpretsDict() { none() }
|
||||
override DataFlow::Node getOutput() { result = this }
|
||||
|
||||
override predicate vulnerableToStrings() { any() }
|
||||
override string getFormat() { result = "NoSQL" }
|
||||
|
||||
override predicate mayExecuteInput() { any() }
|
||||
}
|
||||
|
||||
/** The `$function` query operator executes its `body` string as JavaScript. */
|
||||
private class FunctionQueryOperator extends API::CallNode, NoSqlQuery::Range {
|
||||
private class FunctionQueryOperator extends DataFlow::Node, Decoding::Range {
|
||||
API::Node dictionary;
|
||||
DataFlow::Node query;
|
||||
|
||||
FunctionQueryOperator() {
|
||||
this = mongoCollection().getMember(mongoCollectionMethodName()).getACall() and
|
||||
query =
|
||||
this.getParameter(0)
|
||||
.getASubscript*()
|
||||
.getSubscript("$function")
|
||||
.getSubscript("body")
|
||||
.asSink()
|
||||
dictionary =
|
||||
mongoCollection()
|
||||
.getMember(mongoCollectionMethodName())
|
||||
.getACall()
|
||||
.getParameter(0)
|
||||
.getASubscript*() and
|
||||
query = dictionary.getSubscript("$function").getSubscript("body").asSink() and
|
||||
this = dictionary.asSink()
|
||||
}
|
||||
|
||||
override DataFlow::Node getQuery() { result = query }
|
||||
override DataFlow::Node getAnInput() { result = query }
|
||||
|
||||
override predicate interpretsDict() { none() }
|
||||
override DataFlow::Node getOutput() { result = this }
|
||||
|
||||
override predicate vulnerableToStrings() { any() }
|
||||
override string getFormat() { result = "NoSQL" }
|
||||
|
||||
override predicate mayExecuteInput() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,7 +75,7 @@ module NoSqlInjection {
|
||||
|
||||
/** A JSON decoding converts a string to a dictionary. */
|
||||
class JsonDecoding extends Decoding, StringToDictConversion {
|
||||
JsonDecoding() { this.getFormat() = "JSON" }
|
||||
JsonDecoding() { this.getFormat() in ["JSON", "NoSQL"] }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user