JS: Type track pg model

This commit is contained in:
Asger Feldthaus
2020-05-15 16:57:28 +01:00
parent f7771f17d1
commit 84cd02cf01
4 changed files with 54 additions and 30 deletions

View File

@@ -123,21 +123,8 @@ private module MySql {
* Provides classes modelling the `pg` package.
*/
private module Postgres {
/** Gets an expression of the form `new require('pg').Client()`. */
DataFlow::SourceNode newClient() {
result = DataFlow::moduleImport("pg").getAConstructorInvocation("Client")
}
/** Gets a data flow node that holds a freshly created Postgres client instance. */
DataFlow::SourceNode client() {
result = newClient()
or
// pool.connect(function(err, client) { ... })
result = newPool().getAMethodCall("connect").getCallback(0).getParameter(1)
}
/** Gets an expression that constructs a new connection pool. */
DataFlow::SourceNode newPool() {
DataFlow::InvokeNode newPool() {
// new require('pg').Pool()
result = DataFlow::moduleImport("pg").getAConstructorInvocation("Pool")
or
@@ -145,25 +132,55 @@ private module Postgres {
result = DataFlow::moduleImport("pg-pool").getAnInstantiation()
}
private DataFlow::SourceNode clientOrPool(DataFlow::TypeTracker t) {
/** Gets a data flow node referring to a connection pool. */
private DataFlow::SourceNode pool(DataFlow::TypeTracker t) {
t.start() and
(result = client() or result = newPool())
result = newPool()
or
exists(DataFlow::TypeTracker t2 | result = clientOrPool(t2).track(t2, t))
exists(DataFlow::TypeTracker t2 |
result = pool(t2).track(t2, t)
)
}
/** Gets a data flow node referring to a connection pool. */
DataFlow::SourceNode pool() {
result = pool(DataFlow::TypeTracker::end())
}
/** Gets a creation of a Postgres client. */
DataFlow::InvokeNode newClient() {
result = DataFlow::moduleImport("pg").getAConstructorInvocation("Client")
}
/** Gets a data flow node referring to a Postgres client. */
private DataFlow::SourceNode client(DataFlow::TypeTracker t) {
t.start() and
(
result = newClient()
or
result = pool().getAMethodCall("connect").getABoundCallbackParameter(0, 1)
)
or
exists(DataFlow::TypeTracker t2 |
result = client(t2).track(t2, t)
)
}
/** Gets a data flow node referring to a Postgres client. */
DataFlow::SourceNode client() {
result = client(DataFlow::TypeTracker::end())
}
private DataFlow::SourceNode clientOrPool() {
result = clientOrPool(DataFlow::TypeTracker::end())
result = client() or result = pool()
}
/** A call to the Postgres `query` method. */
private class QueryCall extends DatabaseAccess, DataFlow::ValueNode {
override MethodCallExpr astNode;
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
QueryCall() { this = clientOrPool().getAMethodCall("query") }
override DataFlow::Node getAQueryArgument() {
result = DataFlow::valueNode(astNode.getArgument(0))
result = getArgument(0)
}
}
@@ -177,14 +194,12 @@ private module Postgres {
string kind;
Credentials() {
exists(DataFlow::InvokeNode call, string prop |
(call = newClient() or call = newPool()) and
this = call.getOptionArgument(0, prop).asExpr() and
(
prop = "user" and kind = "user name"
or
prop = "password" and kind = prop
)
exists(string prop |
this = [newClient(), newPool()].getOptionArgument(0, prop).asExpr()
|
prop = "user" and kind = "user name"
or
prop = "password" and kind = prop
)
}

View File

@@ -14,6 +14,7 @@
| postgres2.js:30:16:30:41 | 'SELECT ... number' |
| postgres3.js:15:16:15:40 | 'SELECT ... s name' |
| postgres5.js:8:21:8:25 | query |
| postgresImport.js:4:18:4:43 | 'SELECT ... number' |
| sequelize2.js:10:17:10:118 | 'SELECT ... Y name' |
| sequelize.js:8:17:8:118 | 'SELECT ... Y name' |
| sequelizeImport.js:3:17:3:118 | 'SELECT ... Y name' |

View File

@@ -36,3 +36,5 @@ module.exports.query = function (text, values, callback) {
console.log('query:', text, values);
return pool.query(text, values, callback);
};
module.exports.pool = pool;

View File

@@ -0,0 +1,6 @@
const { pool } = require("./postgres1");
pool.connect((err, client, done) => {
client.query('SELECT $1::int AS number', ['1'], function(err, result) {
});
});