I have a generic API call that I want to use across different tables in my DB. This is the SQL query
SELECT * FROM $column_name WHERE step != Failed
I want to do this avoiding the possibility of sql injection by doing something like this
var type = req.params.type;
var sql = 'SELECT * FROM ? WHERE step != FALSE';
postgres.client.query(sql, [ type ], function(err, results) {}
This doesn't work, and throws a syntax error. I did some poking around and tried doing $1, and ??, instead of ? but nothing worked. I did verify that the type variable is the proper value.
When I run this,
var type = req.params.type;
var sql = 'SELECT * FROM ' + type + ' WHERE step != FALSE';
postgres.client.query(sql, [ type ], function(err, results)
It works fine. What's the deal here??
As I understand You use node-postgres (alias: pg
) module.
And for that module there is no ?
or ??
substitution.
You've to use $N
notation, but pg driver does not allow dynamic table names.
So here's workaround:
1) create constants/tableNames.js
file that will contain list of allowed table names to be used:
module.exports = [
'users',
'profiles',
... and etc tables that You have
];
2) create db/queries/selectFromTable.js
with following content that will be responsible for query generation with checking table name in allowed table names:
const tableNames = require('../../constants/tableNames.js');
module.exports = (tableName, queryTail = 'WHERE step != FALSE') => {
if (tableNames.includes(tableName)) {
return 'SELECT * FROM '+tableName+' '+queryTail;
}
return 'SELECT NULL';
};
3) and use it in Your code as in example:
const selectFrom = require('db/queries/selectFromTable.js');
app.get('/records/:table', async (req, res) => {
try {
const table = req.params.table;
const query = selectFrom(table);
const result = await postgres.client.query(query, []);
res.status(200).send(result.rows);
/**
* OR:
* const table = req.params.table;
* const something = req.query.something;
* const query = selectFrom(table, 'WHERE step != FALSE AND something = $1::text');
* const result = await postgres.client.query(query, [something]);
* res.status(200).send(result.rows);
*/
}
catch (error) {
res.status(500).send(error);
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.