transaction prevent nodejs node injection example createconnection javascript mysql node.js sql-injection node-mysql

javascript - prevent - npm mysql



Impedir la inyección de SQL en Node.js (4)

La biblioteca node-mysql realiza automáticamente el escape cuando se usa como ya lo hace. Ver https://github.com/felixge/node-mysql#escaping-query-values

¿Es posible evitar las inyecciones de SQL en Node.js (preferiblemente con un módulo) de la misma manera que PHP tenía Declaraciones preparadas que protegen contra ellos.

¿Si es así, cómo? Si no, ¿cuáles son algunos ejemplos que pueden omitir el código que he proporcionado (ver más abajo).

Algún contexto:

Estoy haciendo una aplicación web con una pila back-end que consiste en Node.js + MySql usando el módulo node-mysql . Desde la perspectiva de la usabilidad, el módulo es excelente, pero aún no ha implementado algo parecido a las Declaraciones preparadas de PHP (aunque sé que está en el proceso).

Desde mi punto de vista, la implementación de declaraciones preparadas de PHP, entre otras cosas, ayudó mucho en la prevención de las inyecciones de SQL. Sin embargo, me preocupa que mi aplicación node.js esté abierta a ataques similares, incluso con el escape de cadena proporcionado de manera predeterminada (como en el fragmento de código a continuación).

node-mysql parece ser el conector mysql más popular para node.js, así que me preguntaba qué otras personas podrían estar haciendo (si es que hay algo) para dar cuenta de este problema, o si incluso es un problema con node.js para comenzar (no estoy seguro de cómo esto no sería, ya que la entrada del usuario / cliente está involucrada).

¿Debo cambiar a node-mysql-native por el momento, ya que proporciona declaraciones preparadas? Dudo en hacer esto, porque no parece ser tan activo como node-mysql (aunque eso solo puede significar que está completo).

Aquí hay un fragmento del código de registro del usuario, que usa el módulo sanitizer , junto con la sintaxis preparada de tipo statement-node de node-mysql (que, como mencioné anteriormente, escapa el carácter), para evitar scripts en sitios cruzados e inyecciones sql, respectivamente:

// Prevent xss var clean_user = sanitizer.sanitize(username); // assume password is hashed already var post = {Username: clean_user, Password: hash}; // This just uses connection.escape() underneath var query = connection.query(''INSERT INTO users SET ?'', post, function(err, results) { // Can a Sql injection happen here? });


La biblioteca tiene una sección en el archivo Léame sobre cómo escapar. Es nativo de Javascript, por lo que no sugiero cambiar a node-mysql-native . La documentación establece estas pautas para escapar:

Editar: node-mysql-native es también una solución de Javascript puro.

  • Los números quedan intactos
  • Los booleanos se convierten a cadenas true / false
  • Los objetos de fecha se convierten a YYYY-mm-dd HH:ii:ss strings
  • Los búferes se convierten en cadenas hexagonales, por ejemplo, X''0fa5''
  • Las cadenas se escapan con seguridad
  • Las matrices se convierten en listas, por ejemplo, [''a'', ''b''] convierte en ''a'', ''b''
  • Las matrices anidadas se convierten en listas agrupadas (para inserciones masivas), por ejemplo, [[''a'', ''b''], [''c'', ''d'']] convierten en (''a'', ''b''), (''c'', ''d'')
  • Los objetos se convierten en pares key = ''val'' . Los objetos anidados se convierten en cadenas.
  • undefined / null se convierten a NULL
  • NaN / Infinity se dejan como están. MySQL no los admite, y tratar de insertarlos como valores desencadenará errores de MySQL hasta que implementen el soporte.

Esto le permite hacer cosas como estas:

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'' });

Tan bien como esto:

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'' });

Además de esas funciones, también puedes usar las funciones de escape:

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

Para escapar de los identificadores de consulta:

mysql.escapeId(identifier);

Y como respuesta a su comentario sobre declaraciones preparadas:

Desde una perspectiva de usabilidad, el módulo es excelente, pero aún no ha implementado algo similar a las Declaraciones preparadas de PHP.

Las declaraciones preparadas están en la lista de todo para este conector, pero este módulo al menos le permite especificar formatos personalizados que pueden ser muy similares a las declaraciones preparadas. Aquí hay un ejemplo del archivo Léame:

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)); };

Esto cambia el formato de consulta de la conexión para que pueda usar consultas como esta:

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


La forma más fácil es manejar todas las interacciones de su base de datos en su propio módulo que exporta a sus rutas. Si su ruta no tiene contexto de la base de datos, SQL no puede tocarla de todos modos.


Me doy cuenta de que esta es una publicación más antigua, pero parece que nunca se marcó una respuesta, así que lo lanzaré por ahí.

Con respecto a las pruebas si un módulo que está utilizando es seguro o no, hay varias rutas que puede tomar. Voy a tocar los pros / contra de cada uno para que pueda tomar una decisión más informada.

Actualmente no hay vulnerabilidades para el módulo que está utilizando, sin embargo, esto a menudo puede llevar a una falsa sensación de seguridad, ya que muy bien podría existir una vulnerabilidad que explota actualmente el paquete de módulo / software que está utilizando y no sería alertado a un problema hasta que el vendedor aplique una corrección / parche.

  1. Para mantenerse al tanto de las vulnerabilidades, deberá seguir listas de correo, foros, IRC y otras discusiones relacionadas con la piratería. PRO: A menudo, puede darse cuenta de que hay problemas potenciales dentro de una biblioteca antes de que un proveedor haya sido alertado o haya emitido una corrección / parche para remediar la posibilidad de ataque a su software. CON: Esto puede consumir mucho tiempo y consumir muchos recursos. Si va por esta ruta, un bot usando fuentes RSS, análisis de registro (IRC chat logs) y / o un scrapper web usando frases clave (en este caso node-mysql-native) y notificaciones pueden ayudar a reducir el tiempo de trolling de estos recursos.

  2. Cree un fuzzer, use un fuzzer u otro marco de vulnerabilidad como metasploit , sqlMap , etc. para ayudar a detectar problemas que el proveedor puede no haber buscado. PRO: Este puede ser un método seguro para garantizar un nivel aceptable ya sea que el módulo o software que está implementando sea seguro para el público. CON: Esto también lleva tiempo y es costoso. El otro problema se derivará de falsos positivos, así como la revisión sin educación de los resultados donde reside un problema pero no se nota.

La seguridad y la seguridad de las aplicaciones en general pueden consumir mucho tiempo y recursos. Una cosa que los gerentes siempre usarán es una fórmula para determinar la efectividad del costo (mano de obra, recursos, tiempo, pago, etc.) de realizar las dos opciones anteriores.

De todos modos, me doy cuenta de que esta no es una respuesta de "sí" o "no" que podría haber estado esperando, pero no creo que nadie pueda decírselo hasta que realice un análisis del software en cuestión.