Preventing SQL injection in Node.js

前端 未结 5 1977
青春惊慌失措
青春惊慌失措 2020-11-22 16:48

Is it possible to prevent SQL injections in Node.js (preferably with a module) in the same way that PHP had Prepared Statements that protected against them.

If so, h

5条回答
  •  轮回少年
    2020-11-22 17:01

    The library has a section in the readme about escaping. It's Javascript-native, so I do not suggest switching to node-mysql-native. The documentation states these guidelines for escaping:

    Edit: node-mysql-native is also a pure-Javascript solution.

    • Numbers are left untouched
    • Booleans are converted to true / false strings
    • Date objects are converted to YYYY-mm-dd HH:ii:ss strings
    • Buffers are converted to hex strings, e.g. X'0fa5'
    • Strings are safely escaped
    • Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
    • Nested arrays are turned into grouped lists (for bulk inserts), e.g. [['a', 'b'], ['c', 'd']] turns into ('a', 'b'), ('c', 'd')
    • Objects are turned into key = 'val' pairs. Nested objects are cast to strings.
    • undefined / null are converted to NULL
    • NaN / Infinity are left as-is. MySQL does not support these, and trying to insert them as values will trigger MySQL errors until they implement support.

    This allows for you to do things like so:

    var userId = 5;
    var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
      //query.sql returns SELECT * FROM users WHERE id = '5'
    });
    

    As well as this:

    var post  = {id: 1, title: 'Hello MySQL'};
    var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
      //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
    });
    

    Aside from those functions, you can also use the escape functions:

    connection.escape(query);
    mysql.escape(query);
    

    To escape query identifiers:

    mysql.escapeId(identifier);
    

    And as a response to your comment on prepared statements:

    From a usability perspective, the module is great, but it has not yet implemented something akin to PHP's Prepared Statements.

    The prepared statements are on the todo list for this connector, but this module at least allows you to specify custom formats that can be very similar to prepared statements. Here's an example from the readme:

    connection.config.queryFormat = function (query, values) {
      if (!values) return query;
      return query.replace(/\:(\w+)/g, function (txt, key) {
        if (values.hasOwnProperty(key)) {
          return this.escape(values[key]);
        }
        return txt;
      }.bind(this));
    };
    

    This changes the query format of the connection so you can use queries like this:

    connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
    //equivalent to
    connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");
    

提交回复
热议问题