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 condición siempre es verdadera: la base devuelve todas las filas, incluida la oculta.
Breve historia
| Año | Hito |
|---|---|
| 1998 | La revista Phrack publica una de las primeras descripciones públicas de lo que hoy llamamos inyección SQL |
| 2000 | El CERT/CC publica un aviso sobre etiquetas HTML maliciosas en páginas web; el nombre cross-site scripting se populariza esos años |
| 2001 | Nace OWASP, Open Worldwide Application Security Project, una fundación abierta dedicada a la seguridad de aplicaciones |
| 2003 | Primera edición del OWASP Top 10, la lista de los riesgos web más importantes |
| 2010–2017 | La inyección ocupa el primer lugar del Top 10 en las ediciones 2010, 2013 y 2017 |
| 2021 | La 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
| Lugar | Intérprete en riesgo |
|---|---|
| Buscadores y filtros de una tienda en línea | Base de datos SQL |
| Paneles que hacen ping, comprimen o convierten archivos | Shell del sistema |
| Comentarios, perfiles y mensajes que otros ven | Navegador |
| Interfaces web de routers y equipos de red | Shell del equipo |
| API que reciben JSON y consultan bases NoSQL | Motor de consultas NoSQL |
| Inicios de sesión contra un directorio corporativo | LDAP |
Conceptos clave
| Concepto | Qué significa |
|---|---|
| Intérprete | Programa que ejecuta texto como instrucciones: motor SQL, shell, navegador |
| Payload | El dato preparado para cambiar el significado de una instrucción; en el curso solo usará payloads académicos |
| Fuente | Lugar por donde entra un dato no confiable, como un parámetro de la URL |
| Sumidero | Función que entrega el dato a un intérprete, como cursor.execute |
| Parametrizar | Enviar la instrucción y los valores por separado al intérprete |
| Codificar la salida | Convertir caracteres especiales en texto inofensivo para el contexto donde caen |
| Lista de permitidos | Conjunto cerrado de valores aceptados; lo contrario de prohibir lo "peligroso" |
| CWE | Nú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.