Reporte – Cross Site Scripting
Table of Contents
ToggleINTRODUCCIÓN
A continuación se presenta de forma detallada un reporte técnico sobre la Resolución del laboratorio “Reflected XSS in a JavaScript URL with some characters blocked” de la plataforma Portswigger. El mismo se establece con un análisis de riesgo con respecto al impacto que esta puede generar. Esto incluye CWE, Criticidad, CVSS Score, CVSS Vector y sus Componentes afectados. Sumado a ello, se especificarán las mitigaciones pertinentes, detalles técnicos del pentest y los links de referencias.
ANÁLISIS DE RIESGO
CWE-79 | Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) |
IMPACTO | MEDIO |
CVSS BASE SCORE | 4.3 |
CVSS 3.1 VECTOR | AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N |
COMPONENTES AFECTADOS | https://LAB-ID.web-security-academy.net/post?postId=post_number Parámetro: postId=post_number |
EXPLICACIÓN | La vulnerabilidad Cross Site Scripting del tipo “Reflected” permite la ejecución de código Javascript cuya salida se refleja en el navegador. De esta forma, a través de ingeniería social, un atacante podría obtener datos como la dirección IP y/o cookies de sesión de un usuario. |
RECOMENDACIONES
1) Filtrar y validar los datos de entrada: Se recomienda utilizar listas de caracteres permitidos y rechazar cualquier entrada que contenga código o secuencias sospechosas, por ejemplo: <script>alert()</script>.
A continuación se detallan algunos ejemplos:
Escapes de caracteres especiales: Al mostrar datos en el DOM, se debe asegurar de escapar caracteres especiales para evitar ataques de inyección de código (por ejemplo XSS)
const escapedHTML = escapeHTML(userInput);
Donde escapeHTML podría ser una función personalizada o utilizando una biblioteca como he:
const he = require(‘he’);
const escapedHTML = he.encode(userInput);
Validación del lado del servidor: Se recomienda implementar una validación más estricta y segura en el lado del servidor para garantizar la integridad de los datos. Por ejemplo, el siguiente es un ejemplo de validación de longitud en el lado del servidor (Node.js):
if (userInput.length < 5) {
res.status(400).send(‘La entrada es demasiado corta’);
return;
}
2) Válidar y Sanitizar entradas específicas: Se recomienda adaptar las técnicas de validación y sanitización según el contexto de las entradas. Por ejemplo:
HTML:
Usar htmlspecialchars o funciones equivalentes para escapar caracteres especiales.
Utilizar strip_tags para eliminar tags HTML no permitidos.
JavaScript:
Codificar cadenas JSON correctamente usando JSON.stringify.
Evitar la inclusión de entradas de usuario directamente en scripts.
CSS:
Evitar incluir entradas de usuario directamente en estilos CSS.
Usar htmlspecialchars para escapar contenido CSS dinámico.
3) Evitar Renderizar HTML Directamente: Cuando se muestren datos proporcionados por el usuario, se recomienda evitar renderizar HTML directamente desde dichas entradas. En lugar de ello, es mejor utilizar funciones como innerText o textContent en lugar de innerHTML en el lado del cliente para evitar la interpretación de código HTML.
4) Escapar datos en la salida: Se debe verificar que los datos no se interpreten como un código ejecutable de forma automática, antes de mostrar los datos ingresados por los usuarios en las páginas web. Es decir, si la entrada está dentro de una cadena JavaScript, se necesita un codificador que realice “unicode” escapando. Por ejemplo:
<script>document.write(‘<script>x=»‘+jsEscape(untrustedValue)+‘»;<\/script>’)</script> |
5) Colocar cabeceras de seguridad: Estas pueden ser XSS-PROTECTION y CSP (Content Security Policy). Por ejemplo, con esta última, se podría colocar:
default–src ‘self’; script–src ‘self’; object–src ‘none’; frame–src ‘none’; base–uri ‘none’; |
Esta política especifica qué recursos, como imágenes y scripts, solo pueden cargarse desde el mismo origen que la página principal.
6) Actualización y Parches: Se recomienda mantener actualizadas todas las herramientas y librerías utilizadas.
7) Educar en Materia de Seguridad informática: Se recomienda educar al personal y/o trabajadores en la seguridad de los datos con respecto a la confidencialidad, integridad y disponibilidad de los mismos a través de talleres o cursos pertinentes.
DETALLES TÉCNICOS
Se procedió a recopilar información con respecto a la estructura y tecnologías que posee dicha aplicación web.
Por tanto, teniendo en cuenta los artículos del sitio web, se puede observar la siguiente función JavaScript en el Botón “Back to Blog” al final de los mismos.
También puede observarse desde el código fuente como se ve en la siguiente captura.
La misma hace referencia al artículo en cuestión, a través del parámetro “PostId” en la URL, cuando se intenta volver a la página de inicio.
Entonces teniendo en cuenta el href tag JavaScript perteneciente al botón “Back to Blog”, se procedió a colocar el siguiente payload, seguido del parámetro PostId en la URL:
&‘},x=x=>{throw/****/onerror=alert,’Hello XSS‘},toString=x,window+»,{x:’ |
Por tanto, sabiendo que la aplicación web bloquea ciertos caracteres, debido a distintas pruebas y seguridad en las cabeceras, se procedió a utilizar dicho exploit con los siguientes argumentos:
1- El “&” se utiliza como separador de parámetros para enviar los valores de usuario a través de una petición GET.
2- Se utiliza la declaración throw, separada con un comentario en blanco para evitar la restricción de espacios.
3- Como throw es una declaración, no se puede utilizar como expresión. Por tanto, se deben usar funciones de flecha x=x⇒ con el fin de crear un bloque para que se pueda usar la declaración de lanzamiento.
4- La función de alert se asigna al controlador de excepciones onerror.
5- Luego, para llamar a dicha función, se asigna la propiedad toString y la activamos forzando una conversión de cadena con window.
Por lo tanto, la petición completa que ejecutaría el servidor sería la siguiente:
javascript:fetch(‘/analytics’, {method:’post’,body:’/post%3fpostId%3d1&’},x=x=>{throw/****/onerror=alert,’Hello XSS’},toString=x,window+»,{x:’‘}).finally(_ => window.location = ‘/’ |
Esto se puede observar en la siguiente captura.
Por lo tanto, un usuario no autenticado puede obtener ciertos datos como la cookie de sesión colocando los siguientes caracteres:
…alert,document.cookie… |
O incluso la dirección ip:
…alert,window.location.hostname… |
Esto se puede observar en la siguiente captura.
De esta manera, un atacante podría obtener datos confidenciales de los usuarios, e incluso, acceder a los mismos.