system onlinepath: /guias/hacking/sqli-xss-y-csrf/mode: knowledge_baselocal:
Hacking ético · Nivel intermedio

SQLi, XSS y CSRF explicados con su defensa

Las tres comparten una raíz: el servidor confía en algo que no debería. En SQLi confía en que la entrada es solo dato; en XSS, en que el contenido es solo texto; en CSRF, en que una petición válida viene de quien dice. Corregirlas es dejar de confiar.

14 min de lectura▣ Actualizada el ◇ Por Underc0de
Respuesta rápida

SQLi, XSS y CSRF son las tres vulnerabilidades web más comunes, y comparten una raíz: el servidor confía en algo que no debería. La inyección SQL ocurre cuando la entrada del usuario se mezcla con la consulta a la base de datos y se ejecuta como código; se corrige con consultas parametrizadas, que según OWASP hacen que «la base de datos siempre distinga entre código y datos». El cross-site scripting (XSS) ocurre cuando un valor controlado por el atacante termina interpretado como script en el navegador de la víctima; se corrige con codificación de salida según el contexto. El cross-site request forgery (CSRF) engaña al navegador de una víctima autenticada para que envíe una petición que ella no pidió; se corrige con un token anti-CSRF y el atributo SameSite en las cookies. Nada de esto se prueba sobre sistemas ajenos: se practica en una aplicación propia o en laboratorios hechos para eso.

Ver índice de contenidos
  1. 01La raíz común: confianza mal puesta
  2. 02SQL injection
  3. 03Cross-site scripting
  4. 04Cross-site request forgery
  5. 05Las tres, una al lado de otra
  6. 06Cómo se prueban
  7. 07Errores frecuentes
  8. 08Preguntas frecuentes
  9. 09Fuentes

La raíz común: confianza mal puesta

Las tres vulnerabilidades web más comunes, su causa de fondo y su defensa según OWASP. La idea central en el encabezado: las tres nacen de que el servidor confía en algo que no debería, y corregirlas es dejar de confiar. Primera columna, inyección SQL: la entrada del usuario se concatena dentro de una consulta a la base de datos y se termina ejecutando como código en lugar de tratarse como dato; el ejemplo clásico es un campo que en vez de un nombre contiene un fragmento de instrucción que cierra la cadena y agrega una condición siempre verdadera; la defensa principal según OWASP son las consultas parametrizadas, que separan el código de los datos de modo que la base de datos siempre distinga entre uno y otro, con las consultas preparadas primero, los procedimientos almacenados como equivalente y la validación por lista de permitidos para las partes que no admiten parámetros como los nombres de tabla; el escape manual queda como último recurso frágil que OWASP desaconseja como defensa principal. Segunda columna, cross-site scripting: un valor controlado por el atacante termina interpretado como script en el navegador de la víctima; la defensa es la codificación de salida según el contexto donde se inserta el dato —cuerpo HTML, atributo, JavaScript, CSS o URL—, porque cada contexto necesita una codificación distinta y usar la equivocada deja el hueco abierto, más el uso de sumideros seguros que tratan el dato como texto, la sanitización con una biblioteca probada cuando hay que permitir HTML enriquecido, y una política de seguridad de contenido como capa adicional. Tercera columna, cross-site request forgery: se engaña al navegador de una víctima autenticada para que envíe una petición que ella no quiso hacer, aprovechando que las cookies de sesión viajan solas; la defensa son los tokens anti-CSRF impredecibles y ligados a la sesión, el atributo SameSite en las cookies como refuerzo que no reemplaza al token, y la verificación de encabezados; y OWASP desaconseja explícitamente confiar solo en comprobar el referente o en un CAPTCHA. Al pie, la regla que une las tres: la defensa nunca está en filtrar la entrada buscando lo malo, sino en tratar cada dato según lo que es y dónde va.
Las tres nacen de una confianza mal puesta. Corregirlas es tratar cada dato según lo que es y dónde va.

Antes de verlas por separado conviene fijar lo que tienen en común, porque es lo que hace que las defensas se parezcan:

El patrón detrás de las tres

En SQLi el servidor confía en que la entrada es solo un dato, y resulta ser código. En XSS confía en que un contenido es solo texto, y el navegador lo interpreta como script. En CSRF confía en que una petición bien formada viene de quien dice venir, y no. La defensa nunca es «filtrar lo malo»: es tratar cada dato según lo que es y dónde va.

Por eso este trío se estudia junto. Entendida la raíz, cada corrección deja de ser una receta que memorizar y pasa a ser una consecuencia lógica.

SQL injection

Ocurre cuando la entrada del usuario se concatena dentro de una consulta a la base de datos. El motor no distingue qué parte escribió el programador y qué parte llegó de afuera: ejecuta todo como una sola instrucción.

text
# El error: construir la consulta pegando texto.
consulta = "SELECT * FROM usuarios WHERE nombre = '" + entrada + "'"

# Si 'entrada' es un nombre normal, funciona.
# Si 'entrada' es:  ' OR '1'='1
# la consulta pasa a ser:
SELECT * FROM usuarios WHERE nombre = '' OR '1'='1'
# ...y la condición es siempre verdadera: devuelve todos los usuarios.

La defensa principal, según la hoja de prevención de OWASP, son las consultas parametrizadas (o preparadas): la consulta se define con marcadores de posición y los valores se envían por separado, de modo que —en palabras de OWASP— «la base de datos siempre distinga entre código y datos, sin importar qué entrada se proporcione».

text
# La corrección: la consulta y los datos viajan separados.
consulta = "SELECT * FROM usuarios WHERE nombre = ?"
ejecutar(consulta, [entrada])

# Ahora 'entrada' es SIEMPRE un dato. Aunque contenga comillas y
# palabras SQL, nunca se interpreta como parte de la instrucción.

La jerarquía de defensas que ordena OWASP es clara: primero consultas parametrizadas; los procedimientos almacenados como equivalente si se implementan bien; la validación por lista de permitidos para lo que no admite parámetros, como el nombre de una tabla o de una columna, mapeando la entrada a un conjunto de valores aprobados; y como refuerzo, el menor privilegio de la cuenta de base de datos. El escape manual queda como último recurso, y sobre él OWASP es explícito: «esta metodología es frágil comparada con otras defensas, y NO podemos garantizar que evite todas las inyecciones SQL en todas las situaciones».

Cross-site scripting

Ocurre cuando un valor controlado por el atacante termina en una página y el navegador de la víctima lo interpreta como código en lugar de mostrarlo como texto. El ejemplo real que cubrió el blog de Underc0de es ilustrativo: un XSS en el panel web de un programa malicioso permitió a investigadores observar sesiones activas y hasta secuestrar el panel.

La causa de fondo es la misma que en SQLi, pero el «motor» es otro: acá el que confunde código con texto es el navegador. Y la corrección, según OWASP, depende de un concepto central: el contexto de salida.

i
Por qué no hay una sola forma de codificar

OWASP lo dice sin rodeos: «usar el método de codificación equivocado puede introducir debilidades o dañar la funcionalidad». Un dato que se inserta en el cuerpo HTML se codifica distinto que uno que va en un atributo, y ambos distinto que uno dentro de JavaScript, de CSS o de una URL. La misma entrada, en cinco lugares distintos, necesita cinco codificaciones distintas. Por eso la regla no es «codificar», es «codificar según dónde va».

En la práctica eso se traduce en cuatro capas que OWASP ordena así:

  • Codificación de salida según el contexto. La defensa central: transformar los caracteres especiales para el lugar exacto donde se inserta el dato.
  • Sumideros seguros. Preferir las operaciones del navegador que tratan el dato como texto —asignar contenido de texto, usar los métodos que fijan atributos— y evitar las que interpretan HTML.
  • Sanitización para HTML enriquecido. Cuando la aplicación tiene que aceptar HTML del usuario, usar una biblioteca probada que quite lo peligroso y devuelva una cadena segura. Nunca hacerlo a mano.
  • Política de seguridad de contenido. Como capa adicional, no como defensa principal: reduce el daño si algo se escapa, pero no reemplaza a la codificación.

Los marcos de trabajo modernos codifican por defecto, y ahí está buena parte de la solución. El riesgo aparece en sus puertas de escape —las funciones que insertan HTML sin procesar—, que existen por comodidad y son exactamente donde reaparece el XSS.

Cross-site request forgery

Las dos anteriores inyectan algo; esta es distinta. En CSRF el atacante no inyecta código: engaña al navegador de una víctima ya autenticada para que envíe una petición que la víctima no quiso hacer. Aprovecha que el navegador adjunta solo las cookies de sesión a cada petición hacia un sitio, sin preguntar quién la originó.

text
# La víctima tiene la sesión abierta en su banco. Visita una página
# del atacante, que contiene algo tan simple como una imagen oculta:
<img src="https://banco.example/transferir?a=atacante&monto=1000">

# El navegador pide esa "imagen" y, como va hacia el banco,
# adjunta la cookie de sesión. Si el banco solo mira la cookie,
# la transferencia se procesa. La víctima nunca la pidió.

La defensa que ordena OWASP tiene una principal y dos refuerzos:

  • Token anti-CSRF. Un valor secreto, único por sesión e impredecible, que el servidor genera y espera de vuelta en cada operación que cambia estado. La página del atacante no puede conocerlo, así que su petición forjada llega sin él y se rechaza. OWASP recomienda el patrón de token sincronizado y, para servicios sin estado, el de cookie de doble envío firmada.
  • Atributo SameSite en la cookie. Instruye al navegador a no enviar la cookie en peticiones que vienen de otro sitio. Es un refuerzo valioso, pero OWASP advierte que «no reemplaza una defensa CSRF adecuada en la mayoría de los despliegues».
  • Verificar el origen. Comprobar encabezados que indican de dónde viene la petición, como una capa más.
!
Dos cosas que OWASP desaconseja explícitamente

Un CAPTCHA no sirve como defensa CSRF: está pensado para distinguir humanos de bots, no para este problema. Y el patrón de cookie de doble envío en su forma simple —sin firmar— es evitable por quien pueda escribir cookies en el dominio. Además, y esto es transversal: ninguna operación que cambie estado debe hacerse por GET, porque un enlace o una imagen bastan para dispararla.

Las tres, una al lado de otra

Comparación de SQLi, XSS y CSRF
SQL injectionXSSCSRF
Qué confía malLa entrada es solo datoEl contenido es solo textoLa petición viene de quien dice
Quién se confundeLa base de datosEl navegador de la víctimaEl servidor
A quién afectaLos datos del servidorOtras personas usuariasLa víctima autenticada
Defensa principalConsultas parametrizadasCodificación por contextoToken anti-CSRF
RefuerzoMenor privilegioSumideros seguros y CSPSameSite y no usar GET

Leída así, la tabla deja ver por qué se enseñan juntas y por qué la defensa nunca es un filtro de entrada: cada una se corrige en el punto donde el dato se usa, no en el punto donde entra.

Cómo se prueban

Las tres se prueban con un proxy de intercepción, la herramienta que explica Burp Suite para auditorías web, porque permite editar la petición después de que el navegador la armó. El método, siempre en un entorno propio:

  1. Montar un laboratorio deliberadamente vulnerableExisten aplicaciones hechas para practicar estas familias, además de los laboratorios en línea que ofrecen entornos legales. Nunca un sitio ajeno.
  2. Para SQLi, observar la respuesta a una entrada inesperadaUna comilla, un operador. Un cambio en el comportamiento o un mensaje de error de base de datos es la señal.
  3. Para XSS, comprobar si un valor vuelve sin codificarEnviar un valor reconocible y ver si aparece en la página tal cual, dentro de una etiqueta o un atributo, en lugar de escapado.
  4. Para CSRF, mirar si la operación exige un tokenRepetir una petición que cambia estado sin el token, o desde otra procedencia, y ver si el servidor la acepta igual.
  5. Verificar y documentarReproducir el hallazgo, capturar la petición y la respuesta, y —esto es lo que hace útil a un pentester— proponer la corrección concreta de OWASP para ese caso.

El orden en que se revisa una aplicación entera no se improvisa: lo tiene resuelto la guía de pruebas de OWASP, como se explica en qué es OWASP. Y todo esto se hace dentro del marco de autorización y laboratorio: probar estas vulnerabilidades sobre un sitio de terceros es un delito, aunque el objetivo sea «solo verlo».

Errores frecuentes

  • Defenderse filtrando la entrada en busca de «lo malo». El espacio de variantes es infinito; la defensa va en el punto de uso, no de entrada.
  • Escapar a mano contra SQLi. OWASP lo marca como frágil y como último recurso: la defensa son las consultas parametrizadas.
  • Codificar igual en todos lados contra XSS. Cada contexto de salida necesita su propia codificación.
  • Sanitizar HTML con una expresión regular propia. Se usa una biblioteca probada; hacerlo a mano falla.
  • Confiar solo en SameSite contra CSRF. OWASP dice que no reemplaza al token en la mayoría de los despliegues.
  • Usar un CAPTCHA como defensa CSRF. OWASP lo desaconseja: resuelve otro problema.
  • Permitir operaciones que cambian estado por GET. Un enlace o una imagen bastan para dispararlas.
  • Probar sobre sistemas ajenos. Hay aplicaciones y laboratorios hechos para practicar de forma legal.

Preguntas frecuentes

¿Cuál es la diferencia entre XSS y CSRF?

Se confunden porque las dos involucran a otro sitio, pero atacan cosas opuestas. En XSS el atacante logra que se ejecute código suyo en el navegador de la víctima, así que roba lo que ese navegador puede ver: sesiones, datos de la página, entradas de teclado. En CSRF no ejecuta ningún código: aprovecha que la víctima ya está autenticada para que su navegador envíe, sin saberlo, una petición legítima hacia el sitio de confianza. Dicho corto: XSS roba capacidades del navegador de la víctima; CSRF usa la sesión de la víctima para actuar en su nombre. Por eso también las defensas son distintas: codificación de salida en un caso, token de verificación en el otro.

¿Las consultas parametrizadas frenan toda inyección SQL?

Frenan la forma habitual, que es la concatenación de entrada dentro de la consulta, porque hacen que la base de datos distinga siempre entre código y datos. El matiz es que hay partes de una consulta que no aceptan parámetros: los nombres de tabla o de columna, por ejemplo, o el sentido de un ordenamiento. Para esos casos OWASP recomienda validación por lista de permitidos, mapeando lo que llega del usuario a un conjunto cerrado de valores aprobados. Y como refuerzo transversal, la cuenta de base de datos de la aplicación debe tener el menor privilegio posible, para que una inyección que igualmente ocurra tenga el menor alcance.

¿Por qué hay que codificar distinto en cada contexto?

Porque cada contexto tiene sus propios caracteres peligrosos y sus propias reglas de interpretación. Lo que es inofensivo dentro del cuerpo de una página puede ser explotable dentro de un atributo, de un bloque de JavaScript, de una hoja de estilos o de una URL. OWASP lo advierte directamente: usar el método de codificación equivocado puede introducir debilidades o romper la funcionalidad. Por eso la regla no es simplemente codificar, sino codificar para el lugar exacto donde el dato va a insertarse. La buena noticia es que los marcos de trabajo modernos lo hacen por defecto, y el trabajo se reduce a no usar sus puertas de escape sin entender lo que hacen.

¿Alcanza con SameSite para frenar CSRF?

Ayuda mucho y conviene activarlo, pero OWASP es explícito en que no reemplaza una defensa CSRF adecuada en la mayoría de los despliegues. El motivo es que su comportamiento por defecto todavía permite la cookie en algunas navegaciones de nivel superior con métodos considerados seguros, de modo que si alguna operación que cambia estado quedó accesible por GET, el atributo no la detiene. Por eso la recomendación es usarlo como refuerzo de un token anti-CSRF, no en su lugar, y asegurarse además de que ninguna operación con efectos se pueda disparar con una simple petición GET.

¿Los marcos de trabajo modernos ya resuelven esto?

En buena medida sí, y por eso son la mejor defensa disponible. Los marcos actuales usan consultas parametrizadas en su capa de acceso a datos, codifican la salida por defecto en sus plantillas y suelen traer protección CSRF incorporada. El problema son las puertas de escape: la función que inserta HTML sin procesar, la consulta construida a mano por conveniencia, la ruta que quedó fuera de la protección CSRF. Esas puertas existen para casos legítimos, pero son exactamente donde reaparecen las tres vulnerabilidades. La regla práctica es apoyarse en las defensas por defecto del marco y tratar cada excepción a ellas como código que hay que revisar con especial cuidado.

¿Dónde practico estas vulnerabilidades legalmente?

En aplicaciones diseñadas expresamente para ser vulnerables, que se montan en un laboratorio propio, o en plataformas en línea que ofrecen entornos de práctica legales con objetivos que pone la propia plataforma. Cualquiera de las dos opciones te deja probar inyección, scripting y falsificación de peticiones sin tocar nada ajeno. Lo que no es una opción, bajo ninguna justificación, es probar contra un sitio de terceros: enviar una comilla a un formulario ajeno para ver si es vulnerable ya es intentar acceder a un sistema que no es tuyo, y el hecho de que «solo estabas mirando» no cambia el registro que queda del otro lado ni la calificación legal del acto.

Fuentes

Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.

Aportes de la comunidad Underc0de

  1. Underc0de, blog. Fallo XSS en StealC expone a operadores de malware, por Dragora, 19 de enero de 2026. Caso real que ilustra el impacto de un XSS: un fallo en un panel web permitió observar sesiones activas y secuestrar el propio panel.
  2. Underc0de, foro. Sección Bugs y Exploits. Discusiones de la comunidad sobre estas vulnerabilidades y su explotación en entornos controlados.

Documentación oficial

  1. OWASP. SQL Injection Prevention Cheat Sheet. Las consultas parametrizadas como defensa principal y por qué el escape es frágil, citados textualmente.
  2. OWASP. Cross Site Scripting Prevention Cheat Sheet. La codificación según el contexto de salida y los sumideros seguros.
  3. OWASP. CSRF Prevention Cheat Sheet. Los patrones de token, el atributo SameSite y qué defensas no se recomiendan.
  4. OWASP. OWASP Top 10. La ubicación de la inyección y del control de acceso en la lista de riesgos.
  5. OWASP. Web Security Testing Guide. La metodología para probar estas familias de forma ordenada.