简体   繁体   中英

NodeJS variable substitution for table in sql query

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM