Tema 5

5. Inyección SQL, NoSQL, comandos y otras fallas de inyección

Las fallas de inyección aparecen cuando una aplicación mezcla datos controlados por el usuario con instrucciones que luego interpreta una base de datos, un shell, un directorio o cualquier otro motor. Es una de las familias de vulnerabilidades más peligrosas porque convierte entrada no confiable en comportamiento no previsto.

Objetivo Entender cómo nacen y se explotan las inyecciones
Enfoque Conceptual, técnico y orientado a defensa
Resultado Reconocer patrones inseguros antes de implementarlos

5.1 Introducción

En una aplicación web es muy común que datos recibidos desde el usuario terminen participando en consultas, filtros, búsquedas, comandos del sistema, rutas de archivos o llamadas a otros servicios. Eso no es un problema por sí mismo. El problema aparece cuando esos datos se insertan de forma insegura dentro de una instrucción que otro componente interpreta.

En ese momento la aplicación deja de tratar la entrada como dato y empieza a tratarla, total o parcialmente, como instrucción. Allí nace la inyección.

Las fallas de inyección son especialmente relevantes porque pueden afectar confidencialidad, integridad y disponibilidad, y en algunos casos permitir ejecución remota de acciones críticas.

5.2 Idea central de una inyección

La lógica general es simple:

  1. La aplicación espera recibir un dato.
  2. Ese dato se concatena, interpola o incorpora sin control en una instrucción.
  3. El motor que recibe esa instrucción la interpreta.
  4. El atacante logra alterar la semántica original.

El caso más conocido es SQL Injection, pero el mismo patrón puede aparecer en otros contextos: comandos del sistema operativo, consultas NoSQL, expresiones LDAP, plantillas, rutas o llamadas a intérpretes.

El problema no es que el usuario envíe caracteres especiales. El problema es que la aplicación construya instrucciones mezclando datos externos con sintaxis ejecutable.

5.3 Cuándo una aplicación queda expuesta a inyección

Una aplicación queda expuesta cuando usa entrada no confiable para formar instrucciones dinámicas sin separar claramente datos y código. Esto suele ocurrir por:

  • Concatenar strings para armar consultas o comandos.
  • Confiar en filtros parciales o listas negras de caracteres.
  • Asumir que la validación de frontend ya bloqueó contenido peligroso.
  • Generar consultas dinámicas sin restricciones de contexto.
  • Usar APIs inseguras que esperan cadenas completas en lugar de parámetros estructurados.

5.4 SQL Injection

SQL Injection ocurre cuando datos controlados por el usuario alteran una consulta SQL. Es una de las vulnerabilidades más conocidas y más estudiadas, pero sigue apareciendo porque muchas aplicaciones todavía construyen consultas de forma insegura.

Por ejemplo, si una búsqueda, un login o un filtro incorporan directamente texto enviado por el usuario dentro de una sentencia SQL, un atacante puede modificar la lógica esperada de la consulta.

El impacto depende de los privilegios de la cuenta usada por la aplicación y del diseño del backend, pero puede incluir lectura de datos, alteración de registros, bypass de autenticación o incluso daño mayor si la explotación progresa.

5.5 Qué puede lograr un atacante con SQL Injection

  • Bypass de login o autenticación.
  • Lectura de tablas con datos sensibles.
  • Extracción masiva de información.
  • Modificación o borrado de registros.
  • Evasión de filtros o restricciones.
  • Enumeración de estructura de base de datos.
  • En ciertos escenarios, ejecución de funciones peligrosas del motor.

No todos los sistemas son explotables al mismo nivel, pero incluso una lectura parcial de datos ya puede representar un incidente grave.

5.6 Escenarios típicos de SQL Injection

Escenario Entrada vulnerable Consecuencia posible
Formulario de login Usuario y contraseña usados en consulta dinámica Bypass de autenticación
Búsqueda interna Término interpolado en cláusulas SQL Lectura no autorizada o errores reveladores
Filtros administrativos Ordenamiento, IDs o estados manipulables Exposición o alteración de datos
Reportes Fechas o rangos incorporados sin parametrizar Consulta alterada o ampliada indebidamente

5.7 NoSQL Injection

Las bases NoSQL no eliminan automáticamente el problema de inyección. Si la aplicación construye filtros o expresiones a partir de entrada externa sin control adecuado, también puede exponerse a manipulación.

En sistemas que usan documentos JSON, objetos o operadores especiales, el riesgo aparece cuando el backend acepta estructuras inesperadas, tipos no previstos o condiciones que modifican el comportamiento del filtro original.

Un error común es asumir que porque no existe SQL textual entonces no puede haber inyección. Esa conclusión es falsa. El problema sigue siendo mezclar datos no confiables con lógica interpretable por el motor.

5.8 Command Injection

La inyección de comandos ocurre cuando una aplicación usa entrada del usuario para construir y ejecutar comandos del sistema operativo. Este escenario es extremadamente delicado porque puede permitir que el atacante ejecute acciones directamente en el entorno del servidor.

Esto suele aparecer cuando el backend invoca herramientas del sistema para procesar archivos, consultar servicios, comprimir contenido, convertir formatos o ejecutar scripts auxiliares.

Si el dato externo se concatena dentro del comando sin separación segura, el atacante puede cambiar la orden prevista o encadenar acciones adicionales.

5.9 Impacto de la inyección de comandos

Cuando una inyección de comandos es explotable, sus consecuencias suelen ser especialmente severas:

  • Lectura de archivos del servidor.
  • Ejecución de programas no previstos.
  • Modificación o borrado de contenido.
  • Descarga de malware o herramientas adicionales.
  • Persistencia o movimiento lateral desde el servidor comprometido.

El impacto real depende del usuario del sistema con que corre la aplicación y del entorno donde se despliega, pero puede escalar rápidamente.

5.10 LDAP Injection y otras variantes

El mismo patrón de inyección puede aplicarse a otros intérpretes o motores. Por ejemplo:

  • LDAP Injection: altera filtros o búsquedas en directorios.
  • XPath Injection: modifica consultas sobre documentos XML.
  • Template Injection: afecta motores de plantillas cuando evalúan expresiones peligrosas.
  • Expression Language Injection: aparece cuando expresiones dinámicas se construyen con entrada externa.

Aunque cambie la tecnología, la pregunta defensiva sigue siendo la misma: ¿estamos separando correctamente los datos de la sintaxis interpretable?

5.11 La ilusión de "filtrar caracteres peligrosos"

Una defensa incompleta muy frecuente consiste en intentar bloquear algunos caracteres considerados peligrosos, por ejemplo comillas, punto y coma o símbolos concretos. El problema es que este enfoque suele ser frágil por varias razones:

  • No todos los ataques usan los mismos caracteres.
  • La codificación o el contexto pueden variar.
  • Los motores tienen múltiples formas de expresar condiciones.
  • Un filtro parcial deja una falsa sensación de seguridad.

La defensa real no es "limpiar cadenas hasta que parezcan seguras", sino evitar construir instrucciones de forma insegura.

5.12 Consultas parametrizadas: defensa principal

La defensa más importante contra SQL Injection es usar consultas parametrizadas o prepared statements. Este enfoque separa claramente la estructura de la consulta de los datos proporcionados por el usuario.

Con este mecanismo, el motor recibe por un lado la consulta con placeholders y por otro los valores. Así, los datos se tratan como datos y no como parte de la sintaxis SQL.

Este principio general también se traduce a otras tecnologías: usar APIs estructuradas, builders seguros y mecanismos que separen parámetros de instrucciones.

5.13 ORMs y sensación falsa de seguridad

Muchos frameworks y ORMs reducen el riesgo de SQL Injection cuando se usan correctamente, pero no lo eliminan por arte de magia. Si el desarrollador incorpora consultas dinámicas inseguras, usa fragmentos crudos o concatena partes de la instrucción manualmente, la vulnerabilidad puede reaparecer.

La herramienta ayuda, pero la responsabilidad sigue siendo del diseño y del uso correcto de sus APIs.

5.14 Validación de entrada y defensa en profundidad

Aunque la defensa principal frente a inyección es separar datos e instrucciones, la validación sigue siendo importante. Restringir tipo, longitud, formato y conjunto de valores aceptables reduce exposición y ayuda a detectar comportamientos anómalos antes de que lleguen a capas más sensibles.

Por ejemplo, si un parámetro debe ser un entero positivo o una opción de un conjunto cerrado, el sistema no debería aceptar texto libre arbitrario. Esta validación no reemplaza la parametrización, pero sí agrega una capa útil de control.

5.15 Principio de mínimo privilegio en base de datos

Incluso si una aplicación sufre una inyección, el impacto puede reducirse si la cuenta de base de datos utilizada tiene privilegios mínimos. Un error frecuente es conectar la aplicación con usuarios demasiado poderosos, capaces de modificar tablas, crear estructuras o acceder a datos innecesarios.

El mínimo privilegio ayuda a limitar daño en caso de explotación:

  • Restringe operaciones permitidas.
  • Reduce superficie sobre tablas sensibles.
  • Evita que un problema en un módulo comprometa toda la base.

5.16 Evitar el shell cuando no hace falta

En command injection, una defensa práctica muy importante es evitar invocar el shell del sistema si existe una API nativa o una biblioteca segura que resuelva la misma tarea. Procesar archivos, mover rutas, obtener metadatos o hacer conversiones suele poder hacerse sin construir comandos textuales.

Si no es necesario llamar al sistema operativo, se elimina una gran parte del riesgo.

5.17 Señales de alerta en el diseño

Hay ciertos patrones que deberían encender una alarma temprana durante una revisión de código o diseño:

  • Concatenación de strings para formar consultas.
  • Uso de entradas del usuario para construir filtros complejos sin esquema.
  • Llamadas al sistema operativo con parámetros interpolados.
  • Construcción dinámica de nombres de tablas, columnas o rutas sin controles estrictos.
  • Uso de APIs "raw" sin justificación clara.

5.18 Errores frecuentes al defenderse

  • Confiar solo en reemplazar caracteres especiales.
  • Asumir que un ORM o framework ya resuelve todo automáticamente.
  • Olvidar la validación del lado servidor.
  • Usar cuentas de base de datos con privilegios excesivos.
  • Permitir estructuras JSON arbitrarias en filtros NoSQL.
  • Invocar el shell cuando existe una alternativa más segura.
En inyección, el error más costoso suele ser pensar que el riesgo está controlado solo porque la tecnología usada "parece moderna".

5.19 Ejemplo comparativo de impacto

Tipo de inyección Motor afectado Impacto típico
SQL Injection Base de datos relacional Lectura, alteración o borrado de datos; bypass de autenticación
NoSQL Injection Base documental o clave-valor Filtros manipulados, lectura indebida, evasión de controles
Command Injection Sistema operativo Ejecución de comandos, acceso al servidor, daño amplio
LDAP Injection Directorio Bypass, enumeración o acceso indebido a información del directorio

5.20 Relación con otros temas del curso

Las fallas de inyección están estrechamente relacionadas con varios ejes de seguridad web:

  • Validación de entrada: reduce superficie, aunque no reemplaza la defensa principal.
  • Autorización: una inyección puede saltar controles y acceder a recursos no permitidos.
  • Protección de datos: muchas explotaciones terminan en filtración masiva.
  • Monitoreo: registros y alertas ayudan a detectar intentos anómalos.

Por eso una aplicación robusta no depende de una sola capa, sino de varias medidas que se refuerzan entre sí.

5.21 Qué debes recordar de este tema

  • La inyección aparece cuando datos no confiables alteran instrucciones interpretadas por otro componente.
  • SQL Injection no es la única variante; también existen NoSQL, comandos, LDAP, XPath y otras.
  • La defensa principal es separar datos e instrucciones mediante consultas parametrizadas o APIs seguras.
  • La validación del lado servidor y el mínimo privilegio reducen impacto y exposición.
  • Filtrar algunos caracteres no es una defensa suficiente.

5.22 Conclusión

Las fallas de inyección siguen siendo una de las categorías más peligrosas porque convierten un error de procesamiento de datos en control sobre consultas, comandos o expresiones críticas. Entender su lógica permite identificar patrones inseguros antes de que lleguen a producción y diseñar capas de defensa realmente efectivas.

En el próximo tema estudiaremos otra familia de vulnerabilidades muy frecuente y ligada al navegador: Cross-Site Scripting, o XSS.