Glosario · Seguridad
Inyección SQL
En inglés: SQL injection
También llamado: SQLi, inyecciones SQL, ataque de inyección SQL, inyección de SQL
Definición
Vulnerabilidad en la que la entrada del usuario se concatena en una consulta SQL, lo que permite a un atacante cambiar su lógica para leer, alterar o borrar datos.
La inyección SQL (SQL injection, SQLi) se produce cuando una aplicación construye una sentencia SQL pegando la entrada del usuario en el texto de la consulta. Si la entrada contiene sintaxis SQL, la base de datos la ejecuta como parte de la consulta. Según la consulta y los permisos de la base de datos, un atacante puede saltarse un login, leer datos de otros usuarios, modificar registros o, en el peor de los casos, ejecutar comandos en el servidor. Forma parte de A03 Injection en el OWASP Top 10 de 2021.
Ejemplo
Código Java vulnerable:
String sql = "SELECT * FROM users WHERE email = '" + email + "'";
ResultSet rs = conn.createStatement().executeQuery(sql);
Si email es ' OR '1'='1, la consulta queda así:
SELECT * FROM users WHERE email = '' OR '1'='1'
La condición siempre es verdadera, así que la consulta devuelve todos los usuarios. La solución es una consulta parametrizada, en la que la entrada se envía por separado del texto SQL y nunca puede cambiar su estructura:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE email = ?");
ps.setString(1, email);
ResultSet rs = ps.executeQuery();
Qué comprueba un tester
Con autorización por escrito y en un entorno de pruebas:
- Romper la sintaxis. Envía una comilla simple
'en cada campo de texto, parámetro de URL, cabecera y valor JSON que pueda llegar a una consulta. Un error500, un mensaje de error de la base de datos o un cambio en el número de resultados sugiere que la entrada llega al SQL sin escapar. - Cambiar la lógica. Compara
value' AND '1'='1convalue' AND '1'='2. Si las dos respuestas difieren de una forma que el valor normal no explica, la entrada se está interpretando. - Fijarse en entradas menos obvias. Las columnas de ordenación, los campos de filtro, los cuadros de búsqueda y los parámetros de informes suelen construirse de forma dinámica, porque los nombres de columna no se pueden enlazar como parámetros.
- Revisar el manejo de errores. Los errores de base de datos, los nombres de tablas o los stack traces en las respuestas ya son un hallazgo por sí mismos.
Herramientas como sqlmap automatizan un sondeo más profundo, pero ejecútalas solo contra sistemas que tengas permiso explícito para probar, porque pueden modificar o borrar datos.
Defensas que hay que verificar
Consultas parametrizadas o un ORM usado correctamente en todas partes; listas de valores permitidos (allow-lists) para identificadores dinámicos como las columnas de ordenación; una cuenta de base de datos con el mínimo privilegio; y mensajes de error genéricos. La validación de entradas ayuda, pero no sustituye a la parametrización.