¿Por qué estás aquí?
Ha oído hablar de los ataques de inyección SQL en JavaScript antes, pero no está del todo seguro de cómo se ven en la práctica o si necesita preocuparse por ellos en primer lugar. Quizás esté tratando de averiguar cuán grave podría ser.
En resumen, si estás desarrollando 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 afectado a desarrolladores y sus bases de datos durante décadas. Como desarrollador, recae en ti la responsabilidad de implementar salvaguardas que protejan los datos del usuario y aseguren que tu infraestructura subyacente nunca sea intrudida, explorada o controlada.
Todas las nuevas herramientas dicen que te están ayudando, pero solo hacen que el desarrollo sea más complejo.
Puedes añadir un mapeador objeto-relacional (ORM) como Sequelize y TypeORM para simplificar tu trabajo con bases de datos SQL como MySQL y PostgreSQL, pero no te eximen completamente del riesgo. Los firewalls de aplicaciones web (WAFs) te ayudan a bloquear ataques a nivel de red, pero requieren una infraestructura costosa y un mantenimiento constante. Los escáneres de código pueden ayudarte a identificar fallos obvios, pero hacen mucho menos por las incógnitas desconocidas y las técnicas de día cero al acecho.
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. Luego, iremos un paso más allá al guiarle a través de la instalación de un hotfix global para que sepa, con certeza, que sus aplicaciones están 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 de base de datos, permitiendo 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 imaginar:

¿Qué aspecto tiene una aplicación JavaScript vulnerable?
Comencemos con un ejemplo sencillo 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 código JavaScript de ejemplo a continuación, la aplicación responde a las 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. La aplicación luego 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 pueda parecer inocuo para aquellos no familiarizados con los ataques de inyección SQL, es extremadamente vulnerable. En particular, la aplicación no intenta validar ni sanear la entrada del usuario en busca de cadenas o métodos de codificación potencialmente peligrosos, y concatena la entrada del usuario directamente en la consulta SQL, lo que permite a los atacantes múltiples oportunidades para atacar utilizando métodos comunes de inyección SQL que han existido durante décadas.
Ejemplos de payloads de ataque SQL en JavaScript
La inyección SQL se basa en engañar a tu base de datos MySQL o PostgreSQL para que realice acciones o responda con datos fuera del alcance esperado, debido a la forma en que tu aplicación genera las consultas SQL.
El 1=1 es siempre verdadero un ataque puede devolver la tabla completa de gatos con trucos como apóstrofes o comillas, porque 1=1 es, de hecho, siempre VERDADERO:
- El usuario introduce:
BOBBY TABLES’ OR 1=’1 - La base de datos ejecuta la consulta SQL:
SELECT * FROM Users WHERE Cat = BOBBY TABLES OR 1=1;
Asimismo, los atacantes pueden explotar una = siempre es verdadero ataque para devolver todos los gatos, porque ""="" es siempre VERDADERO:
- El usuario introduce:
" OR ""=" - La base de datos ejecuta la consulta SQL:
SELECT * FROM Cats WHERE CatId ="" or ""="";
Los atacantes suelen explotar cómo las bases de datos manejan los comentarios en línea, e insertando comentarios (/* … */ en una consulta, pueden ofuscar su intención o evadir filtros.
- El usuario introduce:
DR/*hello world*/OP/*sneak attack*/ TABLE Cats; - La base de datos ejecuta la consulta SQL:
DROP TABLE Cats;
Otra estrategia común de inyección SQL en JavaScript es el apilamiento de consultas (query stacking), que permite a los atacantes comenzar con una cadena inofensiva, luego usar un punto y coma (;) para terminar esa declaración y comenzar otra que contenga su inyección. Los atacantes a menudo usan el apilamiento de consultas para eliminar bases de datos enteras de una sola vez con un comando DROP TABLE:
- El usuario introduce:
Bobby; DROP TABLE Cats -- - La aplicación construye su consulta SQL:
const query = "SELECT * FROM Cats WHERE CatId = " + input; - La base de datos ejecuta la consulta SQL:
SELECT * FROM Cats WHERE CatId = BOBBY; DROP TABLE Cats;
¿Qué hay de los ataques de inyección NoSQL?
Los ataques de inyección NoSQL son igualmente peligrosos para la seguridad de tu aplicación y los datos de usuario, pero solo afectan a las pilas tecnológicas que utilizan bases de datos como MongoDB. La principal diferencia radica en el estilo de los ataques, ya que las consultas SQL y NoSQL utilizan una sintaxis completamente única que no se traduce de una categoría a otra.
Si utilizas una base de datos SQL, no corres el riesgo de sufrir ataques de inyección NoSQL, y viceversa.
El camino básico: corregir manualmente todas tus vulnerabilidades de inyección SQL
En este punto, es posible 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.
- Utiliza consultas parametrizadas.: SQL tiene la funcionalidad de 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 anterior, puedes emplear un marcador de posición en tu consulta SQL con un signo de interrogación (
?). Elconnection.query()el método toma 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 sanear la entrada del usuario: Si bien las consultas parametrizadas pueden ayudar a proteger tu base de datos SQL de intrusiones y ataques, también puedes evitar que los usuarios introduzcan cadenas potencialmente peligrosas en tu aplicación.
Una opción es añadir bibliotecas de código abierto para la sanitización y validación a su aplicación. Por ejemplo, puede usar validator.js en el ecosistema JavaScript/Node.js para verificar que un usuario está intentando introducir una dirección de correo electrónico real —y no un ataque de inyección SQL— en tu formulario de registro.
También puedes desarrollar validadores personalizados basados en regex para realizar un trabajo similar, pero tendrás un camino enormemente largo y complejo por delante, con investigación y toneladas de pruebas manuales. Además, ¿puedes realmente interpretar esta expresión regular de ejemplo para la validación de correos electrónicos?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 a la prevención de cadenas como…’ OR 1-’1.Puede intentar investigar y cerrar todas estas oportunidades por su cuenta, pero probablemente preferiría dedicar su tiempo a construir nuevas funcionalidades.
- Despliegue de WAFs o plataformas de seguridad basadas en agentes: Si bien estas soluciones pueden bloquear ataques SQL antes de que siquiera lleguen a su aplicación, o al menos notificarle en tiempo real a medida que ocurren los ataques, conllevan algunas advertencias.
Primero, a menudo son costosas y requieren que lance nueva infraestructura on-premises o en la nube, lo que suele ser mucho más complejo de lo que esperaba como desarrollador que solo quiere desplegar a producción. Segundo, requieren más mantenimiento manual para actualizar el conjunto de reglas, distrayéndole de otras intervenciones manuales para la inyección SQL. Finalmente, a menudo añaden más carga computacional o redirigen todas las solicitudes a través de su plataforma para su análisis, lo que añade latencia y perjudica la experiencia del usuario final.
El gran problema es que las oportunidades para ataques de inyección SQL son como las malas hierbas: puedes eliminarlas todas una vez usando estas herramientas, pero debes estar constantemente vigilante sobre toda tu base de código para asegurarte de que nunca vuelvan a brotar.
Una vía alternativa para resolver ataques de inyección SQL en JavaScript: Aikido Firewall.
Aikido Security ha lanzado recientemente Firewall, un motor de seguridad gratuito y de código abierto que te protege autónomamente de ataques de inyección SQL, y mucho más.
Si no utilizas Node.js, ten en cuenta que empezaremos a dar soporte a otros lenguajes y frameworks en el futuro. Siempre puedes suscribirte a nuestro boletín de productos para saber exactamente cuándo Firewall se expandirá más allá del mundo de JavaScript o enviarnos un correo electrónico a hello@aikido.dev si deseas proponer un lenguaje específico.
Probando una aplicación vulnerable a la inyección SQL de JavaScript
Usemos una aplicación de ejemplo que se incluye con el repositorio de código abierto para mostrar cómo funciona Aikido Firewall. También necesitarás Docker/Docker Compose para desplegar una base de datos MySQL local.
Empieza haciendo un fork del repositorio firewall-node y clonando 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, inicia la aplicación de ejemplo:
node sample-apps/express-mysql2/app.js
Abierto http://localhost:4000 en su navegador para probar la sencilla aplicación de gatos. En el área de texto, escriba algunos nombres de gatos y haga clic en el Añadir botón. Para probar la inyección SQL, puedes hacer clic en el Inyección de prueba enlace o escriba lo siguiente en el área de texto: Kitty'); DELETE FROM cats;-- H y haz clic Añadir de nuevo. De cualquier manera, la aplicación le permite apilar múltiples consultas utilizando algunos comentarios de consulta ingeniosos, eliminando toda la base de datos de gatos.
¿Cómo ocurre esto? Como advertimos anteriormente, esta aplicación simplemente añade cualquier entrada del usuario al final de la consulta SQL, lo cual es intrínsecamente inseguro.
const query = `INSERT INTO cats(petname) VALUES ('${name}');`
Las consecuencias podrían ser menores aquí, pero no es difícil imaginar cómo este error, a menudo inocente, puede tener consecuencias desastrosas para su aplicación en producción.
Bloqueo de inyecciones SQL de JavaScript con Aikido Firewall
Ahora veamos con qué rapidez nuestro motor de seguridad de código abierto bloquea los ataques de inyección SQL de JavaScript sin tener que corregir manualmente cada interacción con la base de datos en tu código.
Si aún no tienes una cuenta de Aikido, adelante y crear uno gratis. Si ya tienes uno, inicia sesión y conecte su cuenta de GitHub. Durante ese proceso, otorga a Aikido acceso para leer tu fork de firewall-node proyecto.
Ir a la Panel de control del firewall y haz clic en Añadir Servicio. Dale un nombre a tu servicio y una vez más elige tu fork para el firewall-node proyecto.

Aikido te indica 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 sobre cómo integrarías nuestro motor de seguridad de código abierto en todas tus aplicaciones Node.js que puedan ser vulnerables a ataques de inyección SQL de JavaScript.

Haz clic en el Generar token botón 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 de Aikido. Copia el token generado, que comienza con AIK_RUNTIME…, y vuelve a tu terminal para ejecutar de nuevo la aplicación de ejemplo, pero ahora con el Firewall completamente habilitado en modo de bloqueo:
AIKIDO_TOKEN=<YOUR-AIKIDO-TOKEN> AIKIDO_DEBUG=true AIKIDO_BLOCKING=true node sample-apps/express-mysql2/app.js
Abierto localhost:4000 y una vez más invoca el ataque de inyección SQL incluido. Esta vez, Aikido te bloqueará en el navegador, generará una salida en los logs de tu servidor web local y creará un nuevo evento. Haz clic en él para ver detalles completos sobre el intento de inyección SQL, incluyendo el payload y dónde tu aplicación generó la peligrosa consulta SQL.

En lugar de preocuparte por proteger tus aplicaciones para siempre contra ataques de inyección SQL en JavaScript, tanto críticos como aún no vistos, Aikido Firewall ofrece un bloqueo integral y una observabilidad sofisticada que te mantiene informado sobre las fuentes de ataque, las cargas útiles comunes y los posibles puntos débiles.
¿Qué sigue?
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 su infraestructura y los datos de sus usuarios contra ataques de inyección SQL de JavaScript, inyección de comandos, contaminación de prototipos, path traversal, y más próximamente.
No estamos diciendo que Firewall deba reemplazar las mejores prácticas de desarrollo para protegerse contra la inyección SQL, como el uso de consultas parametrizadas o nunca confiar en la entrada del usuario, pero también sabemos por experiencia personal que ningún desarrollador es perfecto. Ningún código base está exento de fallos, y los errores honestos ocurren todo el tiempo.
Piense en Firewall como un hotfix global para la inyección SQL. A diferencia de las expresiones regulares desarrolladas a medida, los WAF que inducen latencia o los agentes de seguridad complejos que cuestan un ojo de la cara, realiza este único trabajo extraordinariamente bien y con un impacto insignificante, completamente 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). ⭐
Protege tu software ahora.



.avif)
