Polish documentation, mongoCollectionMethod() and update .expected

This commit is contained in:
jorgectf
2021-06-28 20:55:49 +02:00
parent 3fd1129895
commit 68c683189a
2 changed files with 104 additions and 64 deletions

View File

@@ -11,35 +11,49 @@ private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private module NoSQL {
/** API Nodes returning `Mongo` instances. */
// API Nodes returning `Mongo` instances.
/** Gets a reference to `pymongo.MongoClient` */
private API::Node pyMongo() {
result = API::moduleImport("pymongo").getMember("MongoClient").getReturn()
}
/** Gets a reference to `flask_pymongo.PyMongo` */
private API::Node flask_PyMongo() {
result = API::moduleImport("flask_pymongo").getMember("PyMongo").getReturn()
}
/** Gets a reference to `mongoengine` */
private API::Node mongoEngine() { result = API::moduleImport("mongoengine") }
/** Gets a reference to `flask_mongoengine.MongoEngine` */
private API::Node flask_MongoEngine() {
result = API::moduleImport("flask_mongoengine").getMember("MongoEngine").getReturn()
}
/** Gets a reference to a initialized `Mongo` instance. */
/**
* Gets a reference to a initialized `Mongo` instance.
* See `pyMongo()`, `flask_PyMongo()`
*/
private API::Node mongoInstance() {
result = pyMongo() or
result = flask_PyMongo()
}
/** Gets a reference to a initialized `Mongo` DB instance. */
/**
* Gets a reference to a initialized `Mongo` DB instance.
* See `mongoEngine()`, `flask_MongoEngine()`
*/
private API::Node mongoDBInstance() {
result = mongoEngine().getMember(["get_db", "connect"]).getReturn() or
result = mongoEngine().getMember("connection").getMember(["get_db", "connect"]).getReturn() or
result = flask_MongoEngine().getMember("get_db").getReturn()
}
/** Gets a reference to a `Mongo` DB use. */
/**
* Gets a reference to a `Mongo` DB use.
*
* See `mongoInstance()`, `mongoDBInstance()`.
*/
private DataFlow::LocalSourceNode mongoDB(DataFlow::TypeTracker t) {
t.start() and
(
@@ -56,10 +70,24 @@ private module NoSQL {
exists(DataFlow::TypeTracker t2 | result = mongoDB(t2).track(t2, t))
}
/** Gets a reference to a `Mongo` DB use. */
/**
* Gets a reference to a `Mongo` DB use.
*
* ```py
* from flask_pymongo import PyMongo
* mongo = PyMongo(app)
* mongo.db.user.find({'name': safe_search})
* ```
*
* `mongo.db` would be a `use` of a `Mongo` instance, and so the result.
*/
private DataFlow::Node mongoDB() { mongoDB(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to a `Mongo` collection use. */
/**
* Gets a reference to a `Mongo` collection use.
*
* See `mongoDB()`.
*/
private DataFlow::LocalSourceNode mongoCollection(DataFlow::TypeTracker t) {
t.start() and
(
@@ -73,7 +101,17 @@ private module NoSQL {
exists(DataFlow::TypeTracker t2 | result = mongoCollection(t2).track(t2, t))
}
/** Gets a reference to a `Mongo` collection use. */
/**
* Gets a reference to a `Mongo` collection use.
*
* ```py
* from flask_pymongo import PyMongo
* mongo = PyMongo(app)
* mongo.db.user.find({'name': safe_search})
* ```
*
* `mongo.db.user` would be a `use` of a `Mongo` collection, and so the result.
*/
private DataFlow::Node mongoCollection() {
mongoCollection(DataFlow::TypeTracker::end()).flowsTo(result)
}
@@ -88,19 +126,54 @@ private module NoSQL {
}
}
/** Gets a reference to a `Mongo` collection method. */
/**
* Gets a reference to a `Mongo` collection method.
*
* ```py
* from flask_pymongo import PyMongo
* mongo = PyMongo(app)
* mongo.db.user.find({'name': safe_search})
* ```
*
* `mongo.db.user.find` would be a collection method, and so the result.
*/
private DataFlow::Node mongoCollectionMethod() {
mongoCollection() in [result.(DataFlow::AttrRead), result.(DataFlow::AttrRead).getObject()] and
mongoCollection() = result.(DataFlow::AttrRead).getObject() and
result.(DataFlow::AttrRead).getAttributeName() instanceof MongoCollectionMethodNames
}
/** Gets a reference to a `Mongo` collection method call */
/**
* Gets a reference to a `Mongo` collection method call
*
* ```py
* from flask_pymongo import PyMongo
* mongo = PyMongo(app)
* mongo.db.user.find({'name': safe_search})
* ```
*
* `mongo.db.user.find({'name': safe_search})` would be a collection method call, and so the result.
*/
private class MongoCollectionCall extends DataFlow::CallCfgNode, NoSQLQuery::Range {
MongoCollectionCall() { this.getFunction() = mongoCollectionMethod() }
override DataFlow::Node getQuery() { result = this.getArg(0) }
}
/**
* Gets a reference to a call from a class whose base is a reference to `mongoEngine()` or `flask_MongoEngine()`'s
* `Document` or `EmbeddedDocument` objects and its attribute is `objects`.
*
* ```py
* from flask_mongoengine import MongoEngine
* db = MongoEngine(app)
* class Movie(db.Document):
* title = db.StringField(required=True)
*
* Movie.objects(__raw__=json_search)
* ```
*
* `Movie.objects(__raw__=json_search)` would be the result.
*/
private class MongoEngineObjectsCall extends DataFlow::CallCfgNode, NoSQLQuery::Range {
MongoEngineObjectsCall() {
this =
@@ -114,6 +187,7 @@ private module NoSQL {
override DataFlow::Node getQuery() { result = this.getArgByName(_) }
}
/** Gets a reference to `mongosanitizer.sanitizer.sanitize` */
private class MongoSanitizerCall extends DataFlow::CallCfgNode, NoSQLSanitizer::Range {
MongoSanitizerCall() {
this =

View File

@@ -31,37 +31,23 @@ edges
| mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute | mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute | mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute | mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript | mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search |
| mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute | mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict |
| mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:37:34:37:44 | ControlFlowNode for json_search |
| mongoengine_bad.py:41:21:41:27 | ControlFlowNode for request | mongoengine_bad.py:41:21:41:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:41:21:41:32 | ControlFlowNode for Attribute | mongoengine_bad.py:41:21:41:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:41:21:41:42 | ControlFlowNode for Subscript | mongoengine_bad.py:42:19:42:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:42:19:42:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:45:29:45:49 | ControlFlowNode for Dict |
| mongoengine_good.py:19:21:19:27 | ControlFlowNode for request | mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute | mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript | mongoengine_good.py:20:19:20:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:28:21:28:27 | ControlFlowNode for request | mongoengine_good.py:28:21:28:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:28:21:28:32 | ControlFlowNode for Attribute | mongoengine_good.py:28:21:28:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:28:21:28:42 | ControlFlowNode for Subscript | mongoengine_good.py:29:19:29:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:37:21:37:27 | ControlFlowNode for request | mongoengine_good.py:37:21:37:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:37:21:37:32 | ControlFlowNode for Attribute | mongoengine_good.py:37:21:37:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:37:21:37:42 | ControlFlowNode for Subscript | mongoengine_good.py:38:19:38:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:36:21:36:27 | ControlFlowNode for request | mongoengine_good.py:36:21:36:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:36:21:36:32 | ControlFlowNode for Attribute | mongoengine_good.py:36:21:36:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:36:21:36:42 | ControlFlowNode for Subscript | mongoengine_good.py:37:19:37:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:45:21:45:27 | ControlFlowNode for request | mongoengine_good.py:45:21:45:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:45:21:45:32 | ControlFlowNode for Attribute | mongoengine_good.py:45:21:45:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:45:21:45:42 | ControlFlowNode for Subscript | mongoengine_good.py:46:19:46:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:54:21:54:27 | ControlFlowNode for request | mongoengine_good.py:54:21:54:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:54:21:54:32 | ControlFlowNode for Attribute | mongoengine_good.py:54:21:54:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:54:21:54:42 | ControlFlowNode for Subscript | mongoengine_good.py:55:19:55:43 | ControlFlowNode for Attribute() |
| mongoengine_good.py:63:21:63:27 | ControlFlowNode for request | mongoengine_good.py:63:21:63:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:63:21:63:32 | ControlFlowNode for Attribute | mongoengine_good.py:63:21:63:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:63:21:63:42 | ControlFlowNode for Subscript | mongoengine_good.py:64:19:64:43 | ControlFlowNode for Attribute() |
| pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute |
| pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript |
| pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() |
@@ -111,22 +97,12 @@ nodes
| mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search |
| mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:37:34:37:44 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search |
| mongoengine_bad.py:41:21:41:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:41:21:41:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:41:21:41:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:42:19:42:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:45:29:45:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_good.py:19:21:19:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
@@ -135,22 +111,14 @@ nodes
| mongoengine_good.py:28:21:28:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:28:21:28:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:29:19:29:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_good.py:37:21:37:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:37:21:37:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:37:21:37:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:38:19:38:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_good.py:36:21:36:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:36:21:36:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:36:21:36:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:37:19:37:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_good.py:45:21:45:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:45:21:45:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:45:21:45:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:46:19:46:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_good.py:54:21:54:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:54:21:54:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:54:21:54:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:55:19:55:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_good.py:63:21:63:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:63:21:63:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:63:21:63:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:64:19:64:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
@@ -166,8 +134,6 @@ nodes
| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | This | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:37:34:37:44 | ControlFlowNode for json_search | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:37:34:37:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:37:34:37:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | user-provided value |
| mongoengine_bad.py:45:29:45:49 | ControlFlowNode for Dict | mongoengine_bad.py:41:21:41:27 | ControlFlowNode for request | mongoengine_bad.py:45:29:45:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:45:29:45:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:41:21:41:27 | ControlFlowNode for request | user-provided value |
| pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict | pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict | This | pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | user-provided value |