Search code examples
sqlprepared-statementsql-injection

Should non-variable column names be prepared in a prepared query?


An example given for using prepared statements with the mysql package on npm looks like this:

var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = ['users', 'id', userId];
sql = mysql.format(sql, inserts);

'users' and 'id' here are hardcoded. userId is a variable to be provided by the user. Given that 'users' and 'id' are not provided by the user, is there any sense in including those in the query preparation? Would it be less secure to do the following?

var sql = "SELECT * FROM users WHERE id = ?";
var inserts = [userId];
sql = mysql.format(sql, inserts);

Solution

  • SQL parameters are used only for values, hence cannot be used for column or table names. Behind the scene, when preparing a statement, the RDBMS needs to fully understand the query that will later on be executed. Changing a column or table name does change the meaning of a query, so this is not supported.

    Bottom line, you mentionned that the column and table names do not come from user input, so that removes the risk of SQL injection anyway. If they were coming from outside the program, then a solution would be to programmatically verify them (eg against predefined list of values).