flawopen.com/Cross-Site Scripting
Cross-Site Scripting
El cross-site scripting ocurre cuando una página incluye texto de un usuario de forma que el navegador lo interpreta como HTML o JavaScript, y se ejecuta para otros usuarios con la autoridad del propio sitio. La corrección es la misma en todas partes: codificar cada valor para el lugar exacto donde se escribe, sanitizar los pocos campos que deben admitir HTML y respaldar ambas cosas con una Content Security Policy. Elige tu lenguaje abajo para ver las APIs exactas, el código vulnerable y el corregido, y las reglas de CI que lo detectan.
Explicación en Lenguaje Sencillo (ELI5)
Un periódico publica cartas de lectores en sus propias páginas. Un lector escribe una carta maquetada exactamente como un aviso de la dirección: 'Suscriptores: llamen a este número y dicten los datos de su tarjeta para renovar.' Impresa con la tipografía del periódico, los lectores la creen como si la hubiera escrito el director. XSS es un sitio web que imprime el texto de un visitante en su propia página, donde el navegador lo trata como código del propio sitio, con el acceso del sitio a tu cuenta. Escapar es imprimir cada carta dentro de un recuadro de cita bien marcado, para que ninguna pueda pasar por un aviso de la dirección.
Conceptos Clave y Términos
- Cross-site scripting (CWE-79)
- Una página web incluye datos no fiables sin neutralizarlos para el navegador, así que el marcado o el script de esos datos se interpreta y ejecuta en el origen de la página, con acceso a su DOM, sus cookies y sus APIs.
- Reflected, stored and DOM-based XSS
- El XSS reflejado devuelve datos de la petición directamente en la respuesta, normalmente mediante un enlace preparado. El XSS almacenado guarda el valor y lo sirve a todos los visitantes. El XSS basado en DOM ni siquiera pasa por el servidor: el JavaScript del cliente copia datos de la URL o del almacenamiento a un sink como
innerHTML. - Contextual output encoding
- Cada contexto de salida necesita su propia codificación: entidades HTML para texto de elementos y atributos entre comillas, escape de cadenas JavaScript dentro de scripts, codificación por porcentajes en parámetros de URL y comprobación de esquema en
hrefysrc. Codificar como HTML un valor puesto dentro de un script no basta. - Sanitizing vs encoding
- Codificar muestra el marcado como texto. Cuando los usuarios deben enviar formato, pasa el HTML por un sanitizador de lista permitida (DOMPurify, nh3 como sucesor de bleach, OWASP Java HTML Sanitizer, HtmlSanitizer, ammonia) que conserve las etiquetas permitidas y elimine scripts, manejadores de eventos y URLs
javascript:. - Content Security Policy (CSP)
- Una cabecera de respuesta que indica al navegador qué scripts pueden ejecutarse. Un
script-srcbasado en nonce y sin'unsafe-inline'bloquea la mayoría de los scripts inyectados aunque se cuele un error de codificación, yrequire-trusted-types-for 'script'cierra los sinks del DOM.
Flujo de Ataque Paso a Paso
Texto no fiable llega a una página
Un término de búsqueda, un campo de perfil, un comentario, un fragmento de URL o una respuesta de API se incluye al construir la página en el servidor o al actualizarla en el navegador.
Se escribe sin la codificación correcta
El escape de la plantilla está desactivado, el valor va a un contexto de script o de URL que el escape HTML no cubre, o el código del cliente lo asigna a innerHTML. El valor de prueba inofensivo <img src=x onerror=alert(1)> sobrevive intacto.
El navegador lo interpreta como código
El navegador de la víctima construye un elemento <img> real y dispara onerror, o ejecuta un enlace javascript: al hacer clic.
El script actúa como el sitio
Se ejecuta con el origen del sitio: puede leer la página, llamar a las APIs del sitio con las cookies o tokens de la víctima, cambiar lo que ve el usuario y enviar formularios en su nombre.
Guías de XSS por lenguaje
Lista de Verificación de Seguridad para Ingeniería
- Renderiza cada página con un motor de plantillas con escape automático activado y revisa cada excepción (
|safe,Html.Raw,dangerouslySetInnerHTML,raw,unsafe { },{!! !!}). - Codifica para el contexto exacto: texto HTML y atributos entre comillas, cadenas JavaScript, parámetros de URL; nunca construyas HTML ni JavaScript concatenando cadenas.
- Sanitiza el HTML aportado por usuarios con un sanitizador de lista permitida mantenido, en el punto donde se muestra.
- Permite solo
httpyhttpsen las URLs aportadas por usuarios antes de que lleguen ahref,srco a la navegación. - Envía una Content-Security-Policy basada en nonce, sin
'unsafe-inline', junto conX-Content-Type-Options: nosniff. - Guarda los tokens de sesión en cookies
HttpOnly,SecureySameSite=Lax, no enlocalStorage.