Saltar al contenido
Lectura13 minPreview

Qué es la inyección: datos e instrucciones

Antes de ver código vulnerable conviene tener claro de qué hablamos: qué es la inyección, de dónde viene, por qué sigue en el OWASP Top 10 y qué palabras usará en todo el curso.

Qué es la inyección

La inyección es una falla en la que un dato que viene de fuera termina siendo ejecutado como parte de una instrucción. Toda inyección nace del mismo error de diseño: una aplicación arma una instrucción para otro sistema, que llamamos intérprete, y en medio de esa instrucción coloca datos externos. Si el intérprete no puede distinguir dónde termina la orden y dónde empieza el dato, un dato bien elegido cambia el significado de la orden.

Un intérprete es cualquier programa que recibe texto y lo ejecuta como instrucciones. En una aplicación web hay tres muy comunes:

  • El motor de base de datos, que ejecuta SQL.
  • La shell del sistema operativo, que ejecuta comandos.
  • El navegador del visitante, que interpreta HTML y JavaScript.

Una analogía de ventanilla

Un funcionario rellena un formulario impreso: "Entregar el expediente de: ______ a su titular", y copia tal cual el nombre que usted le dicta. Si usted dicta "Ana Mora a su titular. Además, entregar todos los expedientes", el formulario ahora dice algo que nadie autorizó, porque usa el mismo espacio para la orden y para el dato. La solución no es pedirle que "tenga cuidado con las palabras raras", sino una casilla separada cuyo contenido nunca se lee como orden. En software eso se llama separar código y datos, la idea que repetirá todo el curso.

Cómo se ve en una línea de código

# Peligroso: si texto trae una comilla, cierra la cadena y lo que sigue es SQL
consulta = "SELECT nombre FROM productos WHERE nombre LIKE '%" + texto + "%'"
 
# Seguro: la estructura viaja por un lado y el valor por otro
cursor.execute("SELECT nombre FROM productos WHERE nombre LIKE ?", ("%" + texto + "%",))

El programador pensó en un dato; con la primera línea, el motor ve código. La animación muestra cómo ocurre con el dato clásico de prueba.

La aplicación arma la consulta WHERE name = con una casilla para el dato entre comillas. Un dato normal cabe en la casilla y devuelve una fila. El dato del atacante empieza con una comilla que cierra la cadena antes de tiempo: OR 1=1 y el comentario pasan a ser SQL y la base devuelve todas las filas, incluso la oculta. Con una consulta parametrizada, el mismo texto viaja aparte y no devuelve nada.

La condición siempre es verdadera: la base devuelve todas las filas, incluida la oculta.

[fig] La comilla del dato cierra la cadena de la plantilla y el resto del texto pasa a ser código. Parametrizar separa estructura y valor: el texto sigue siendo solo un dato.

Breve historia

AñoHito
1998La revista Phrack publica una de las primeras descripciones públicas de lo que hoy llamamos inyección SQL
2000El CERT/CC publica un aviso sobre etiquetas HTML maliciosas en páginas web; el nombre cross-site scripting se populariza esos años
2001Nace OWASP, Open Worldwide Application Security Project, una fundación abierta dedicada a la seguridad de aplicaciones
2003Primera edición del OWASP Top 10, la lista de los riesgos web más importantes
2010–2017La inyección ocupa el primer lugar del Top 10 en las ediciones 2010, 2013 y 2017
2021La inyección pasa a A03 y absorbe al XSS, que antes tenía categoría propia

De ahí el nombre de esta serie: "A03" es el código de la categoría en la edición 2021. En el OWASP Top 10:2025 la inyección pasa al quinto lugar, A05:2025 Inyección, y sigue incluyendo el XSS; en sus reportes cite ambas: A05:2025 (A03:2021).

Por qué importa

Si la solución se conoce desde hace décadas, ¿por qué sigue pasando? Porque concatenar cadenas es cómodo, porque hay código heredado que nadie toca, porque los frameworks seguros traen "escapes de emergencia" que se usan sin pensar y porque se confía en datos "internos" que alguna vez escribió una persona externa.

Para quien defiende no es opcional: el desarrollador la evita, el revisor de código la encuentra antes de producción, el analista de SOC la reconoce en los registros y el auditor la reporta con su CWE. Quien no la entiende deja pasar fallas que exponen datos personales, con consecuencias legales en Costa Rica bajo la Ley 8968.

Dónde aparece

LugarIntérprete en riesgo
Buscadores y filtros de una tienda en líneaBase de datos SQL
Paneles que hacen ping, comprimen o convierten archivosShell del sistema
Comentarios, perfiles y mensajes que otros venNavegador
Interfaces web de routers y equipos de redShell del equipo
API que reciben JSON y consultan bases NoSQLMotor de consultas NoSQL
Inicios de sesión contra un directorio corporativoLDAP

Conceptos clave

ConceptoQué significa
IntérpretePrograma que ejecuta texto como instrucciones: motor SQL, shell, navegador
PayloadEl dato preparado para cambiar el significado de una instrucción; en el curso solo usará payloads académicos
FuenteLugar por donde entra un dato no confiable, como un parámetro de la URL
SumideroFunción que entrega el dato a un intérprete, como cursor.execute
ParametrizarEnviar la instrucción y los valores por separado al intérprete
Codificar la salidaConvertir caracteres especiales en texto inofensivo para el contexto donde caen
Lista de permitidosConjunto cerrado de valores aceptados; lo contrario de prohibir lo "peligroso"
CWENúmero que identifica un tipo de debilidad de software, como CWE-89

Cómo leer las sintaxis del curso

En las fichas de herramientas verá formas generales como bandit [OPCIONES] -r RUTA. Los corchetes indican algo opcional, las MAYÚSCULAS son un valor que usted reemplaza y los puntos suspensivos indican que se puede repetir. Para pedir ayuda, casi todas las herramientas aceptan --help; en Python, help(sqlite3.connect) muestra la documentación de una función.