Server-Side XSS in Dynamic PDF
Arsenal completo de comandos en la cheatsheetMuchas aplicaciones generan PDF "al vuelo" (facturas, informes, exportaciones) renderizando HTML con una librería como wkhtmltopdf, mPDF, dompdf o PhantomJS. Si esa librería interpreta HTML y JavaScript y el PDF incluye datos controlados por el usuario sin sanear, tenemos un XSS del lado servidor (SSXSS): la inyección no se ejecuta en el navegador de la víctima, sino en el motor de renderizado del servidor, con acceso a su contexto.
Por qué es más grave que un XSS normal. El conversor corre en el servidor y, a menudo, permite cargar recursos con el esquema file://. Un XSS clásico roba cookies; este lee el sistema de ficheros del servidor. El vector típico es un XMLHttpRequest (o un <iframe>/<embed>) apuntando a file://:
<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(this.responseText)};
x.open("GET","file:///etc/passwd");
x.send();
</script>El contenido del fichero se escribe en el documento y aparece en el PDF generado. Si el fichero da problemas de formato (claves, binarios), se envuelve en <pre> para preservar saltos de línea, o se codifica con btoa(...) para sacarlo en Base64 y decodificarlo después.
Objetivos habituales. /etc/passwd (confirma usuarios y el fallo), claves SSH privadas (/home/<user>/.ssh/id_rsa) para saltar a una sesión interactiva, ficheros de configuración con credenciales, código fuente de la propia aplicación. También puede derivar en SSRF (cargar http:// interno).
Cómo detectarlo. Cualquier funcionalidad que exporte a PDF datos que el usuario introduce (nombre, metadatos, comentarios) es candidata. Se confirma metiendo HTML simple (<b>, <h1>) en un campo y viendo si se renderiza en el PDF en lugar de aparecer literal. Si el punto de inyección tiene límites de longitud, buscar otro campo menos restringido (un título, una descripción, unos metadatos).
Defensa. Sanear/escapar todo dato de usuario antes de pasarlo al conversor; deshabilitar JavaScript y el acceso a esquemas locales (file://) en la configuración de la librería; ejecutar el generador en un entorno aislado (contenedor sin secretos, sin red interna); preferir librerías que traten la entrada como texto, no como HTML activo. Relacionado con lectura de ficheros locales como objetivo final.
Máquinas donde se aplica
- BookHackTheBox