0Pricing
Frontend Academy · Lección

Prevención de XSS: codificación de salida y CSP

Comprenda el XSS reflejado, almacenado y basado en el DOM, escape la salida controlada por el usuario, evite innerHTML con datos no confiables y añada una cabecera Content Security Policy.

Prevención de XSS: codificación de salida y CSP es una lección gratuita de Frontend Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Frontend Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Frontend Academy incluye 4 lecciones en total.

¿Qué es XSS?

Cross-Site Scripting ocurre cuando un atacante inyecta JavaScript ejecutable en su página. El navegador lo ejecuta con los privilegios de su origen, lo que permite robar cookies, secuestrar sesiones, alterar la página y redirigir a malware.

Las tres variantes de XSS

Almacenado: el script malicioso se guarda en la base de datos y se sirve a todos los visitantes. Reflejado: la entrada se devuelve en la respuesta (?q=<script>...). Basado en DOM: el JavaScript del cliente escribe datos no confiables en el DOM.

La causa principal: innerHTML con datos no confiables

Usar innerHTML (o v-html, dangerouslySetInnerHTML) con cadenas controladas por el usuario es el principal vector de XSS.

// BAD: user input rendered as HTML
el.innerHTML = userComment;  // attacker submits <img onerror=alert(1)>

// Vue equivalent:
<div v-html="userComment"></div>  // same bug

// React equivalent:
<div dangerouslySetInnerHTML={{ __html: userComment }} />  // same bug

Codificación de salida (la opción segura predeterminada)

Trate las cadenas no confiables como texto, no como HTML. React, Vue, Angular y Svelte lo hacen de forma predeterminada en la interpolación {value}.

// SAFE: text content, not HTML
el.textContent = userComment;  // <script> shows as literal text

// React (auto-escaped):
<div>{userComment}</div>

// Vue (auto-escaped):
<div>{{ userComment }}</div>

Sanitizar cuando deba renderizar HTML

Si realmente necesita renderizar HTML proporcionado por el usuario (por ejemplo, en editores de texto enriquecido), sanitícelo con DOMPurify; nunca cree su propio sanitizador basado en expresiones regulares.

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userHtml);
el.innerHTML = clean; // strips <script>, on* handlers, dangerous URLs

Validación de URL

Las URL controladas por el usuario en href o src pueden provocar XSS mediante esquemas javascript:.

// BAD:
<a href={userUrl}>Click</a>
// attacker submits: javascript:alert(1)

// GOOD: whitelist protocols:
function safeUrl(url) {
  if (!/^https?:\/\//.test(url) && !url.startsWith('/')) return '#';
  return url;
}

Content Security Policy (CSP)

CSP es un encabezado de respuesta HTTP que indica al navegador qué fuentes de scripts, estilos, imágenes, etc. están permitidas. Incluso si un atacante inyecta un script, el navegador se niega a ejecutarlo.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:

CSP estricta con nonces

Para los scripts en línea que controle, use un nonce distinto en cada solicitud. Los scripts inyectados por un atacante no tendrán el nonce correspondiente.

// Server generates a random nonce per request:
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy', `script-src 'nonce-${nonce}' 'strict-dynamic'`);

// Inject into the HTML:
<script nonce="abc123">/* trusted inline code */</script>

Cookies HttpOnly + Secure

Establezca las cookies de sesión con HttpOnly para que JavaScript no pueda leerlas; incluso si se produce XSS, el atacante no podrá obtener el token de sesión.

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict

Integridad de subrecursos (SRI)

Al cargar scripts de terceros mediante una CDN, use SRI para verificar que el contenido coincide con un hash. Una CDN comprometida no puede servir un script malicioso sin hacer que falle la verificación del hash.

<script
  src="https://cdn.example.com/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

Trusted Types (experimental)

Trusted Types es una funcionalidad del navegador (basado en Chromium) que obliga a los puntos de inserción peligrosos (innerHTML) a recibir un objeto Trusted Type, lo que impide insertar cadenas directamente.

Pruebas para detectar XSS

Intente inyectar <img src=x onerror=alert(1)> en cada entrada de texto que se vuelva a renderizar. Si aparece una alerta, existe un error de XSS. Use herramientas como OWASP ZAP para realizar análisis automatizados.

Comprobación rápida

¿Por qué {userInput} de React es seguro de forma predeterminada, pero dangerouslySetInnerHTML no lo es?

Resumen: prevención de XSS

Opte de forma predeterminada por renderizar texto (React usa {x} y Vue usa {{ x }}, que son seguros). Sanitice con DOMPurify cuando renderice HTML. Use una lista blanca de protocolos de URL. El encabezado CSP (con nonces o 'strict-dynamic') bloquea los scripts inyectados. Las cookies HttpOnly impiden que JavaScript las robe. Use hashes SRI para los scripts de CDN. Pruebe las entradas con payloads clásicos.

Preguntas frecuentes

¿La lección «Prevención de XSS: codificación de salida y CSP» es gratis?

Sí — el texto completo de «Prevención de XSS: codificación de salida y CSP» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Frontend Academy, actualiza a CoddyKit PRO. El curso de Frontend Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Prevención de XSS: codificación de salida y CSP»?

Comprenda el XSS reflejado, almacenado y basado en el DOM, escape la salida controlada por el usuario, evite innerHTML con datos no confiables y añada una cabecera Content Security Policy. Practicas Frontend Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Frontend Academy?

No se requiere experiencia previa. Frontend Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Prevención de XSS: codificación de salida y CSP»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Frontend Academy?

Sí. Cada lección de Frontend Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Prevención de XSS: codificación de salida y CSP
  2. CSRF: cookies SameSite y tokens
  3. Content Security Policy: nonce y hash
  4. Flujos de OAuth desde el frontend
← Volver a Frontend Academy