Tema 5
La inyección ocurre cuando una aplicación mezcla datos controlados por el usuario con instrucciones que serán interpretadas por otro componente, como una base de datos, un intérprete o el sistema operativo. Cuando esa frontera se rompe, el atacante deja de enviar datos y empieza a influir en la lógica ejecutada por el servidor.
Las aplicaciones web necesitan recibir datos y usarlos para hacer cosas útiles: buscar registros, filtrar resultados, autenticar usuarios, guardar comentarios, ejecutar tareas internas, llamar a otros servicios o transformar archivos. El problema aparece cuando la aplicación toma esas entradas y las incorpora de forma insegura dentro de una instrucción que otro componente interpretará.
Ese patrón general se conoce como inyección. No se trata solo de SQL Injection, aunque esa sea la variante más famosa. La misma idea puede afectar motores NoSQL, sistemas operativos, expresiones dinámicas, plantillas, parsers y otros contextos donde el dato del usuario termina influyendo en una sintaxis ejecutable.
En OWASP Top 10, Injection sigue siendo una categoría central porque sus impactos pueden ser devastadores: lectura y modificación masiva de datos, bypass de autenticación, ejecución de comandos, acceso al sistema y compromiso total de la aplicación.
Existe una vulnerabilidad de inyección cuando la aplicación incorpora entrada controlada por el usuario en una consulta, comando o expresión sin separar correctamente los datos de las instrucciones.
El núcleo del problema puede resumirse así:
Injection es especialmente crítica por varias razones:
Por eso esta categoría no debe estudiarse como un conjunto de payloads, sino como una falla estructural de separación entre datos e instrucciones.
La mayoría de las inyecciones nacen del mismo error conceptual: construir instrucciones mediante concatenación de cadenas usando datos externos. Cuando eso ocurre, el sistema deja abierta la posibilidad de que el atacante "rompa" el contexto previsto y agregue significado propio.
Esto puede pasar en múltiples escenarios:
La defensa principal no es adivinar todos los payloads posibles, sino diseñar el sistema para que los datos nunca se conviertan en control del intérprete.
SQL Injection ocurre cuando la aplicación construye consultas SQL de forma insegura incorporando directamente entrada del usuario. Si el atacante altera la estructura de la consulta, puede modificar su significado.
Las consecuencias pueden incluir:
SQL Injection es un caso clásico porque muchas aplicaciones históricamente construyeron consultas concatenando directamente parámetros como usuario, contraseña, búsqueda o identificadores.
No se limita al formulario de login. Puede aparecer en cualquier punto donde la aplicación use entrada externa dentro de una consulta SQL.
A veces la consulta vulnerable no es evidente porque está varios pasos detrás del formulario que el usuario ve en pantalla.
| Objetivo del atacante | Impacto típico |
|---|---|
| Bypass de autenticación | Ingreso sin credenciales válidas |
| Lectura de datos | Exposición de usuarios, contraseñas, pedidos, documentos |
| Alteración de información | Cambios no autorizados en cuentas, saldos o configuraciones |
| Borrado o corrupción | Pérdida de integridad o disponibilidad |
| Escalada técnica | Mayor control sobre la base o sobre el entorno |
El alcance real depende de los permisos que la aplicación tenga sobre la base de datos y de cómo esté segmentado el entorno.
Uno de los escenarios más conocidos es el bypass de autenticación. Si la aplicación arma una consulta SQL insegura con el usuario y la contraseña, el atacante puede alterar la lógica del where para que la consulta devuelva un resultado válido sin necesidad de conocer credenciales reales.
Lo importante aquí no es memorizar cadenas concretas, sino entender la lógica: cuando el servidor le permite al usuario alterar la condición de autenticación, el problema no está en la contraseña, sino en cómo se construyó la consulta.
No siempre la aplicación devuelve errores visibles o resultados completos. A veces la inyección sigue existiendo, pero el atacante debe inferir información a partir del comportamiento del sistema. A esto se lo suele llamar inyección ciega.
Algunas pistas indirectas pueden ser:
Este punto es importante porque muestra que ocultar mensajes de error ayuda, pero no elimina la vulnerabilidad si la consulta sigue siendo manipulable.
Cuando las aplicaciones usan bases de datos NoSQL, el problema de inyección no desaparece. Solo cambia la sintaxis y el contexto. En muchos sistemas NoSQL, los filtros y consultas se construyen con objetos, expresiones o estructuras JSON que también pueden verse alteradas si la aplicación no valida correctamente la entrada.
NoSQL Injection puede permitir:
El error conceptual sigue siendo el mismo: permitir que los datos del usuario entren en el lenguaje de consulta sin control suficiente.
Existe un mito común: "como no usamos SQL, entonces no tenemos SQL Injection y ya está". Eso es una simplificación peligrosa. El riesgo de inyección no depende del nombre del motor, sino de cómo la aplicación construye e interpreta consultas o filtros.
Si un sistema toma estructuras controladas por el cliente y las usa como parte de la consulta sin validación estricta, sigue existiendo una superficie de manipulación.
Command Injection ocurre cuando la aplicación usa entrada del usuario para construir comandos que serán ejecutados por el sistema operativo o por una shell. Si el atacante logra alterar ese comando, puede influir directamente en la ejecución del servidor.
Este tipo de inyección suele ser muy grave porque puede pasar rápidamente del plano de aplicación al plano del host subyacente.
Ejemplos conceptuales donde puede aparecer:
Cuando un atacante logra alterar comandos del sistema, el impacto puede escalar con rapidez.
Aunque el curso aquí se concentra en SQL, NoSQL y comandos, conviene fijar una idea más general: cualquier intérprete puede convertirse en superficie de inyección si recibe entradas no confiables como parte de su lenguaje.
Por eso el pensamiento defensivo debe ser amplio. Siempre que una aplicación genere dinámicamente consultas, expresiones, plantillas o comandos usando entrada externa, hay que preguntarse si el dato puede cambiar la sintaxis ejecutada.
Validar entradas es importante, pero no debe presentarse como única defensa. Un filtro incompleto puede ser bypassado, especialmente cuando se intenta bloquear caracteres o patrones peligrosos manualmente.
Las defensas más robustas son aquellas que evitan estructuralmente la mezcla insegura entre datos e instrucciones, por ejemplo usando consultas parametrizadas o APIs seguras del framework.
La validación sigue siendo valiosa para:
La concatenación de cadenas con datos del usuario dentro de consultas o comandos es uno de los patrones más peligrosos y repetidos en software vulnerable. Aunque resulte rápida de programar, crea una frontera insegura donde el dato puede convertirse en control.
Este patrón debe levantar una alarma inmediata en revisiones de código, especialmente si involucra:
Durante una revisión o prueba, algunos indicios justifican análisis más profundo:
En el caso de SQL, la defensa más importante consiste en usar consultas parametrizadas o sentencias preparadas. La idea es que la estructura de la consulta y los datos se transmitan por canales diferenciados, de modo que el motor no reinterprete la entrada del usuario como parte del lenguaje SQL.
Esta separación es mucho más robusta que intentar escapar manualmente caracteres o bloquear cadenas peligrosas.
En motores NoSQL y otros intérpretes, el principio es similar: construir consultas y filtros mediante APIs seguras, validando fuertemente la estructura esperada y restringiendo operadores o campos permitidos.
En la práctica esto implica:
La mejor defensa contra Command Injection es evitar invocar la shell o comandos del sistema cuando existe una alternativa segura dentro del lenguaje o framework. Si no hay otra opción, deben separarse claramente argumentos, restringirse valores y minimizar privilegios del proceso.
Buenas prácticas:
Aunque exista una inyección, el impacto puede reducirse si la aplicación y sus componentes operan con privilegios limitados. Esto no corrige la vulnerabilidad, pero puede contener daño.
Ejemplos:
Injection puede combinarse con muchas otras categorías del curso:
Esto hace que una sola inyección pueda convertirse en puerta de entrada para compromisos mucho más amplios.
Injection sigue siendo una de las categorías más representativas de la seguridad web porque muestra con claridad un principio esencial: cuando una aplicación deja que datos externos controlen la lógica interna de un intérprete, el atacante gana capacidad real de manipulación sobre el sistema.
En el próximo tema estudiaremos A04: Insecure Design, una categoría que va más allá de errores puntuales de implementación y nos obliga a pensar en cómo una aplicación puede ser insegura desde su propia arquitectura y lógica de negocio.