mariadb-corporation / mariadb-connector-nodejs

MariaDB Connector/Node.js is used to connect applications developed on Node.js to MariaDB and MySQL databases. MariaDB Connector/Node.js is LGPL licensed.
GNU Lesser General Public License v2.1
366 stars 91 forks source link

What's the recommended way to use/change a database for a query? #197

Closed CheyenneForbes closed 2 years ago

CheyenneForbes commented 2 years ago

I'm thinking of the multipleStatements option and the use statement but the documentation warns of potential SQL injections when multipleStatements is enabled

rusher commented 2 years ago

Enabling multipleStatements might be unsafe (opening doors to SQL injection) if your application is building SQL.

Example: query like "SELECT * FROM cart WHERE someValue = '" + val + "'" and passing val = '; CREATE USER 'hackUser'@'%.

The second command CREATE USER 'hackUser'@'%' would then be executed.

multipleStatement is a nice option and safe to use only when using using placeholder.

Example: connection.query('SELECT * FROM cart WHERE someValue = ?', [val]); then there is no risk, parameter are escaped correctly, it would be the same as executing : connection.query('SELECT * FROM cart WHERE someValue = '\'; CREATE USER \'hackUser\'@\'%');

When multipleStatements option is enabled, sql command must never be build 'manually', always using question mark for parameter, and parameter ... as parameter.

edit You can still build sql, but escape parameter properly like : connection.query(`SELECT * FROM cart WHERE someValue = ${connection.escape(val)}`); see documentation

rusher commented 2 years ago

btw, usually, if this is only for a query, the best solution is just to prefix database table, avoiding changing database at all. This will be faster. I.e. connection.query('SELECT * FROM myDB.cart ...'); or if not known beforehand, using escapeId connection.query(`SELECT * FROM ${connection.escapeId(myDB)}.cart ...');