Tres patrones de inyección SQL que aún se distribuyen en Node.js — Y la regla de ESLint que los detecta
En el ecosistema Node.js, la inyección SQL sigue siendo una de las vulnerabilidades más persistentes a pesar de ser ampliamente documentada. No se trata de falta de conocimiento técnico, sino de cómo ciertos patrones de código pasan desapercibidos durante las revisiones. Un fragmento aparentemente inofensivo, como una variable concatenada directamente en una consulta, puede convertirse en un vector de ataque que compromete datos sensibles. En entornos donde se desarrollan aplicaciones a medida con alta exigencia de seguridad, como los que abordamos en Q2BSTUDIO, la prevención de estos fallos es un pilar fundamental.
El primer patrón problemático es la concatenación directa de cadenas dentro de la llamada al método query. Cuando un desarrollador escribe algo similar a SELECT * FROM usuarios WHERE id = seguido de un valor que proviene de una petición HTTP, el código parece inocente a simple vista. El revisor no suele rastrear el origen de esa variable, que puede estar definida varias capas arriba en la función controladora. Este es un error clásico que cualquier equipo de ciberseguridad identifica, pero que en la práctica cotidiana se cuela con frecuencia.
El segundo patrón, igualmente peligroso, utiliza plantillas literales (template literals). La interpolación con ${variable} dentro de una cadena SQL se siente más limpia y moderna, lo que genera una falsa sensación de seguridad. Sin embargo, desde el punto de vista de la base de datos, la consulta sigue siendo una cadena construida con datos no validados. Muchos desarrolladores que evitan la concatenación con el operador + caen en esta trampa por considerar que las plantillas literales son intrínsecamente seguras. En proyectos de software a medida que integran múltiples fuentes de datos, como los que gestionamos con servicios cloud AWS y Azure, este error puede exponer tablas enteras.
El tercer patrón es el más insidioso y el que con mayor frecuencia supera las revisiones de código: la asignación cruzada de variables. Aquí la cadena SQL se construye en una línea anterior, quizás mediante concatenación o interpolación, y se almacena en una variable. Cuando esa variable se pasa al método query, el revisor solo ve un nombre de variable; no hay ningún signo de concatenación en el lugar de la llamada. Para detectarlo, hace falta un análisis de flujo de datos que la mayoría de las revisiones humanas no realizan. En Q2BSTUDIO, donde aplicamos técnicas de inteligencia artificial para optimizar procesos, combinamos esta capacidad con reglas estáticas avanzadas para prevenir estos puntos ciegos.
La solución más efectiva para estos patrones no es un linter genérico de inyección SQL, sino una regla específica para el driver pg de PostgreSQL. Una regla como no-unsafe-query entiende el contrato de la API: sabe que las consultas parametrizadas usan marcadores $1, $2 y un segundo argumento con los valores. No se limita a buscar concatenación cerca de palabras clave SQL, sino que analiza las llamadas a pool.query o client.query, detecta si hay un arreglo de valores no vacío, y marca como infectada cualquier variable que haya sido construida con concatenación o interpolación antes de ser usada. Esta capacidad de rastreo intraprocedimental es clave para atrapar el tercer patrón, el que más daño causa en entornos de producción.
Además, esta regla se integra perfectamente en el flujo de trabajo del desarrollador: se ejecuta en cada pulsación de tecla y en los ganchos de pre-commit, sin necesidad de pipelines complejos de CI. Para equipos que trabajan con servicios inteligencia de negocio o que utilizan Power BI para visualizar datos provenientes de bases PostgreSQL, esta detección temprana evita que vulnerabilidades lleguen a los entornos de explotación. En nuestra experiencia con aplicaciones a medida, la combinación de buenas prácticas de parametrización y herramientas de análisis estático reduce drásticamente la superficie de ataque.
Por supuesto, ningún linter es infalible. Existen falsos positivos cuando se pasan constantes de esquema (como nombres de tablas) que no provienen de entrada del usuario. En esos casos, se recomienda usar funciones de escape de identificadores o reestructurar la consulta. Pero para el 99% de los casos reales, la regla detecta correctamente los tres patrones. En Q2BSTUDIO, al desarrollar agentes IA o soluciones de ia para empresas, aplicamos este mismo nivel de rigor para garantizar que cada capa del software sea resistente a ataques.
Si tu equipo utiliza Node.js con PostgreSQL de forma directa, o incluso si empleas ORMs como Prisma o Knex (que tienen sus propias escotillas de escape), vale la pena revisar qué patrones se están usando en el código base. Una simple variable que se asignó hace dos líneas puede ser la puerta de entrada a un ataque. Para reforzar la seguridad en tus proyectos, en ciberseguridad ofrecemos auditorías que incluyen este tipo de análisis, junto con pruebas de penetración y mejores prácticas para entornos cloud. La prevención es siempre más rentable que la remediación posterior.
Comentarios