¿Por qué estás aquí?
Ya ha oído hablar de los ataques de inyección SQL en JavaScript, pero no está del todo seguro de cómo son en la naturaleza o de si debe preocuparse por ellos en primer lugar. Tal vez estás tratando de averiguar lo malo que podría ser.
En resumen, si estás creando aplicaciones que utilizan bases de datos SQL, como MySQL y PostgreSQL, estás en riesgo: no estás a salvo de los métodos de ataque que han asolado a los desarrolladores y sus bases de datos durante décadas. Como desarrollador, tienes la responsabilidad de implementar barandillas que protejan los datos de los usuarios y garanticen que tu infraestructura subyacente nunca sea invadida, explorada o requisada.
Todas las nuevas herramientas dicen que te ayudan, pero sólo hacen que el desarrollo sea más complejo.
Puede añadir un mapeador objeto-relacional (ORM) como Sequelize y TypeORM para simplificar el trabajo con bases de datos SQL como MySQL y PostgreSQL, pero no le eximen completamente del riesgo. Los cortafuegos de aplicaciones web (WAF) ayudan a bloquear los ataques a nivel de red, pero requieren una infraestructura costosa y un mantenimiento constante. Los escáneres de código pueden ayudarle a identificar fallos evidentes, pero hacen mucho menos por los desconocidos y las técnicas de día cero que acechan.
Le presentaremos una imagen clara de cómo son los ataques de inyección SQL, el riesgo que conllevan y los errores de desarrollo que los hacen posibles. A continuación, le guiaremos a través de la instalación de una revisión global para que sepa, con certeza, que sus aplicaciones son seguras.
Ataques de inyección SQL: ejemplos e implicaciones
La definición más básica de un ataque de inyección SQL es cuando una aplicación permite que una entrada de usuario no validada y no saneada ejecute consultas a la base de datos, lo que permite a un atacante leer la base de datos SQL, modificar registros o eliminarlos a su antojo.
Como de costumbre, XKCD ilustra el peligro de SQL mejor que la mayoría de los escenarios sombríos que podríamos soñar:

¿Qué aspecto tiene una aplicación JavaScript vulnerable?
Empecemos con un sencillo ejemplo de pseudocódigo: una aplicación JavaScript con un elemento de entrada que permite a los usuarios buscar en una base de datos de gatos. En el siguiente ejemplo de código JavaScript, la aplicación responde a solicitudes POST en la ruta /cats para extraer la entrada del usuario del cuerpo de la solicitud y se conecta a la base de datos con una consulta para devolver todos los gatos con un id coincidente. A continuación, la aplicación muestra el gato utilizando la respuesta JSON.
app.post("/cats", (request, response) => {
const query = `SELECT * FROM cats WHERE id = ${request.body.id}`;
connection.query(query, (err, rows) => {
if(err) throw err;
response.json({
data: rows
});
});
});
Aunque este ejemplo puede parecer inocuo para quienes no están familiarizados con los ataques de inyección SQL, es extremadamente vulnerable. En particular, la aplicación no intenta validar o desinfectar la entrada del usuario de cadenas potencialmente peligrosas o métodos de codificación, yconcatenala entrada del usuario directamente en la consulta SQL, lo que permite a los atacantes múltiples oportunidades para atacar utilizando métodos de ataque de inyección SQL comunes que han existido durante décadas.
Ejemplo de carga útil de ataque JavaScript SQL
La inyección SQL consiste en engañar a tu base de datos MySQL o PostgreSQL para que realice una acción o responda con datos fuera del ámbito esperado debido a la forma en que tu aplicación genera las consultas SQL.
En 1=1 siempre es cierto ataque puede devolver toda la tabla de gatos con trucos como apóstrofes o comillas, porque 1=1
es siempre VERDADERO:
- El usuario introduce:
MESAS BOBBY' O 1='1
- La base de datos ejecuta la consulta SQL:
SELECT * FROM Usuarios WHERE Cat = BOBBY TABLES OR 1=1;
Del mismo modo, los atacantes pueden explotar una = siempre es verdad ataque para devolver todos los gatos, porque ""=""
es siempre VERDADERO:
- El usuario introduce:
" OR ""="
- La base de datos ejecuta la consulta SQL:
SELECT * FROM Gatos WHERE CatId ="" o ""="";
Los atacantes suelen aprovecharse de la forma en que las bases de datos gestionan los comentarios en línea, e insertando comentarios (/* ... */)
en una consulta, pueden ofuscar su intención o eludir los filtros.
- El usuario introduce:
DR/*hello world*/OP/*sneak attack*/ TABLE Cats;
- La base de datos ejecuta la consulta SQL:
DROP TABLE Gatos;
Otra estrategia común de inyección SQL en JavaScript es el apilamiento de consultas, que permite a los atacantes comenzar con una cadena inocua y, a continuación, utilizar un punto y coma (;) para terminar esa sentencia y comenzar otra que contenga su inyección. Los atacantes suelen utilizar el apilamiento de consultas para eliminar bases de datos enteras de un solo golpe con un comando DROP TABLE:
- El usuario introduce:
Bobby; DROP TABLE Gatos --
- La aplicación crea su consulta SQL:
const query = "SELECT * FROM Gatos WHERE CatId = " + input;
- La base de datos ejecuta la consulta SQL:
SELECT * FROM Cats WHERE CatId = BOBBY; DROP TABLE Cats;
¿Qué ocurre con los ataques de inyección NoSQL?
Los ataques de inyección NoSQL son igual de peligrosos para la seguridad de tu aplicación y los datos de los usuarios, pero solo afectan a las pilas tecnológicas que utilizan bases de datos como MongoDB. La principal diferencia son los ataques de estilo, ya que las consultas SQL y NoSQL utilizan una sintaxis totalmente única que no se traslada de una categoría a otra.
Si utiliza una base de datos SQL, no corre el riesgo de sufrir ataques de inyección NoSQL, y viceversa.
El camino básico: corregir manualmente todas las vulnerabilidades de inyección SQL
Llegados a este punto, puede que estés menos interesado en cómo son todos los posibles trucos de inyección y más interesado en cómo proteger los datos que tienes en MySQL o PostgreSQL.
- Utilizar consultas parametrizadas: SQL tiene una funcionalidad para desconectar la ejecución de consultas y valores, protegiendo la base de datos de ataques de inyección.Con el ejemplo de JavaScript/Node.js de arriba, puedes emplear un marcador de posición en tu consulta SQL con un signo de interrogación (
?
). Enconnection.query()
toma entonces el parámetro en su segundo argumento, proporcionando los mismos resultados en un método a prueba de inyecciones.
app.post("/cats", (request, response) => {
const query = `SELECT * FROM Cats WHERE id = ?`;
const value = request.body.id;
connection.query(query, value, (err, rows) => {
if(err) throw err;
response.json({
data: rows
});
});
});
- Validar y desinfectar la entrada del usuario: Mientras que las consultas parametrizadas pueden ayudar a proteger su base de datos SQL de intrusiones y ataques, también puede evitar que los usuarios introduzcan cadenas potencialmente peligrosas en su aplicación.
Una opción es añadir a tu aplicación bibliotecas de código abierto para el saneamiento y la validación. Por ejemplo, puede utilizar validador.js en el ecosistema JavaScript/Node.js para comprobar que un usuario está intentando introducir una dirección de correo electrónico real -y no un ataque de inyección SQL- en su formulario de registro.
También puedes desarrollar validadores personalizados basados en regex para realizar un trabajo similar, pero tendrás por delante un camino enormemente largo y complejo con investigación y toneladas de pruebas manuales. Además, ¿realmente puedes interpretar este ejemplo de regex para la validación de correo electrónico?const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
La misma idea se aplica para evitar cadenas como...' O 1-'1.
Puedes intentar investigar y cerrar todas estas oportunidades tú mismo, pero probablemente prefieras dedicar tu tiempo a crear nuevas funciones.
- Implantar WAF o plataformas de seguridad basadas en agentes: Aunque estas soluciones pueden bloquear los ataques SQL incluso antes de que lleguen a tu aplicación, o al menos notificarte en tiempo real cuando se producen los ataques, vienen con algunas advertencias.
En primer lugar, a menudo son caras y requieren que pongas en marcha una nueva infraestructura en las instalaciones o en la nube, que a menudo es mucho más compleja de lo que contrataste como desarrollador que solo quiere enviar a producción. En segundo lugar, requieren más mantenimiento manual para actualizar el conjunto de reglas, lo que le distrae de otras intervenciones manuales contra la inyección SQL. Por último, a menudo añaden más carga computacional, o redirigen todas las solicitudes a través de su plataforma para el análisis, añadiendo latencia y perjudicando la experiencia del usuario final.
El gran problema es que las oportunidades para los ataques de inyección SQL son como las malas hierbas: puedes cortarlas todas una vez utilizando estas herramientas, pero debes estar constantemente atento a toda tu base de código para asegurarte de que no vuelvan a brotar.
Un camino alternativo para resolver los ataques de inyección SQL en JavaScript: Firewall Aikido
Aikido Security acaba de lanzar Firewall, un motor de seguridad gratuito y de código abierto que le proyecta de forma autónoma frente a ataques de inyección SQL, y mucho más.
Si no utiliza Node.js, sepa que empezaremos a dar soporte a otros lenguajes y frameworks en el futuro. Siempre puede suscribirse a nuestro boletín de productos para saber exactamente cuándo Firewall se expande más allá del mundo JavaScript o enviarnos un correo electrónico a hello@aikido.dev si desea lanzar un lenguaje específico.
Probar una aplicación vulnerable a la inyección SQL de JavaScipt
Vamos a utilizar una aplicación de ejemplo que viene con el repositorio de código abierto para mostrar cómo funciona Aikido Firewall. También necesitarás Docker/DockerCompose para desplegar una base de datos MySQL local.
Empieza por hacer un fork del repositorio firewall-node y clona dicho fork en tu estación de trabajo local.
git clone https://github.com/<YOUR-GITHUB-USERNAME>/firewall-node.gitcd firewall-node
Utiliza Docker para desplegar una base de datos MySQL local en el puerto 27015. Este archivo docker-compose.yml también crea contenedores s3mock, MongoDB y PostgreSQL, ya que fue creado para ayudar al equipo de Aikido a probar cómo Firewall bloquea varios ataques.
docker-compose -f sample-apps/docker-compose.yml up -d
A continuación, inicie la aplicación de ejemplo:
node sample-apps/express-mysql2/app.js
Abrir http://localhost:4000
en tu navegador para echar un vistazo a esta sencilla aplicación para gatos. En el área de texto, escriba algunos nombres de gatos y haga clic en el botón Añadir botón . Para probar la inyección SQL, puede hacer clic en el botón Inyección de prueba o escriba lo siguiente en el área de texto: Kitty'); DELETE FROM gatos;-- H
y haga clic en Añadir de nuevo. En cualquier caso, la aplicación te permite apilar varias consultas utilizando algunos comentarios de consulta engañosos, borrando toda la base de datos de gatos.
¿Cómo ocurre esto? Como hemos advertido antes, esta aplicación simplemente añade cualquier entrada del usuario al final de la consulta SQL, lo que es intrínsecamente inseguro.
const query = `INSERT INTO cats(petname) VALUES ('${name}');`
Las consecuencias pueden ser pequeñas en este caso, pero no es difícil imaginar cómo este error a menudo honesto puede tener consecuencias desastrosas para su aplicación de producción.
Bloqueo de la inyección SQL de JavaScript con Aikido Firewall
Veamos ahora con qué rapidez nuestro motor de seguridad de código abierto bloquea los ataques de inyección SQL de JavaScript sin tener que arreglar manualmente cada interacción con la base de datos en su código.
Si aún no tienes una cuenta de Aikido, adelante. haga uno gratis. Si ya tiene uno, inicie sesión y conecta tu cuenta de GitHub. Durante ese proceso, conceda a Aikido acceso para leer su bifurcación del nodo cortafuegos
proyecto.
Ir a la Panel del cortafuegos y haz clic en Añadir servicio. Dé un nombre a su servicio y, una vez más, elija su horquilla para el nodo cortafuegos
proyecto.

Aikido te instruye sobre cómo instalar e implementar Aikido Firewall. Dado que estamos utilizando la aplicación de ejemplo, ese trabajo ya está hecho para ti, pero es una referencia útil para saber cómo llevar nuestro motor de seguridad de código abierto a todas tus aplicaciones Node.js que podrían ser vulnerables a ataques de inyección SQL de JavaScript.

Haga clic en el botón Generar token para crear un token que permita a Aikido Firewall pasar de forma segura información sobre ataques de inyección SQL bloqueados a la plataforma de seguridad Aikido. Copie el token generado, que empieza por AIK_RUNTIME...
y vuelva a su terminal para volver a ejecutar la aplicación de ejemplo, sólo que ahora con el Firewall totalmente activado en modo de bloqueo:
AIKIDO_TOKEN=<YOUR-AIKIDO-TOKEN> AIKIDO_DEBUG=true AIKIDO_BLOCKING=true node sample-apps/express-mysql2/app.js
Abrir localhost:4000
y una vez más invocar el ataque de inyección SQL incluido. Esta vez, Aikido lo bloqueará en el navegador, lo enviará a los registros de tu servidor web local y generará un nuevo evento. Haz clic en él para ver los detalles completos sobre el intento de inyección SQL, incluyendo la carga útil y dónde generó tu aplicación la peligrosa consulta SQL.

En lugar de preocuparse por proteger siempre sus aplicaciones contra los ataques de inyección SQL de JavaScript, tanto los críticos como los que aún no se han visto, Aikido Firewall ofrece un bloqueo completo y una capacidad de observación sofisticada que le mantiene informado sobre las fuentes de ataque, las cargas útiles comunes y los puntos débiles potenciales.
¿Y ahora qué?
Puede instalar e implementar Aikido Firewall en todas sus aplicaciones basadas en Node.js de forma gratuita. Nuestro motor de seguridad embebido de código abierto protege tu infraestructura y datos de usuario contra ataques de inyección SQL de JavaScript, inyección de comandos, contaminación de prototipos, path traversal, y más que vendrán en breve.
No estamos diciendo que Firewall deba reemplazar las mejores prácticas de desarrollo para la protección contra la inyección SQL, como el uso de consultas parametrizadas o no confiar nunca en la entrada del usuario, pero también sabemos por experiencia personal que ningún desarrollador es perfecto. Ninguna base de código es impecable, y los errores honestos ocurren todo el tiempo.
Piense en Firewall como un hotfix global para la inyección SQL. A diferencia de los regex desarrollados a medida, los WAF que inducen latencia o los complejos agentes de seguridad que cuestan un ojo de la cara, hace este trabajo extraordinariamente bien y con un impacto insignificante, totalmente gratis.
Si te gusta lo que has visto, echa un vistazo a nuestra hoja de ruta y dale una estrella a nuestro repositorio de GitHub(https://github.com/AikidoSec/firewall-node). ⭐