Saltar al contenido
← Volver a hallazgos
Agosto 2026CríticaCVSS 9.3Objetivo: plataforma de facturación para clientes (caso anonimizado)

Cuando el UUID no es una autorización: recibos de clientes expuestos encadenando dos IDOR

La ruta que mostraba el recibo de un cliente se protegía con un UUID de 128 bits. Adivinarlo era inviable, así que el equipo dejó de intentarlo y buscó dónde estaba escrito.

  • CWE-639
  • IDOR
  • UUID
  • Cadena de explotación
  • Fuga de PII
  • RGPD

Resumen

La ruta del recibo no comprobaba quién pedía el documento: daba por buena la posesión del UUID. Es la confusión de fondo entre un identificador difícil de adivinar y una autorización.

Un identificador impredecible solo protege mientras nadie pueda leerlo en otro sitio. Aquí se podía leer en dos sitios, y ninguno de los dos era la aplicación: en los servicios que archivan direcciones públicas, donde habían quedado registradas URL de recibo con su identificador dentro, y en una segunda referencia directa insegura, esta con identificadores secuenciales, que los devolvía uno a uno.

Por separado, cada pieza habría pasado por un hallazgo de severidad media. Encadenadas convierten un documento aislado en la lectura de los recibos de toda la cartera de clientes. El fallo está corregido.

Detalles técnicos

La ruta del recibo

Con el UUID en la mano, el recibo se servía sin sesión ni comprobación de titularidad:

Petición: recibo por identificador
GET /clientes/recibos/8f14e45f-ceea-467a-9a1b-3d6c2f0b17ac HTTP/1.1
Host: [OBJETIVO]
 
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="recibo-[REF].pdf"

El documento incluía nombre, dirección fiscal, identificador tributario, concepto e importe del cliente.

Primera fuente: las direcciones ya estaban archivadas

El enlace al recibo se comparte por correo, se pega en un ticket, se abre desde una red corporativa. Cada uno de esos pasos deja rastro fuera de la organización. Buscando en servicios públicos que conservan direcciones (archivos históricos de la web, plataformas de análisis de enlaces y los propios buscadores) aparecieron direcciones de recibo con su UUID dentro, y seguían sirviendo el documento:

Pseudocódigo: búsqueda fuera de la aplicación
UUID_RE = r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
RUTA   = "/clientes/recibos/"

# Ninguna de estas fuentes es del objetivo, y ninguna pide autenticacion
for fuente in (archivo_historico, analisis_de_enlaces, buscadores):
    for url in fuente.buscar(dominio=OBJETIVO, contiene=RUTA):
        uuid = findall(UUID_RE, url)
        if uuid and get(RUTA + uuid[0]).status == 200:
            guardar(uuid[0])   # el documento seguia sirviendose

Segunda fuente: un IDOR clásico que devolvía el UUID

Una funcionalidad secundaria de la propia aplicación aceptaba un identificador numérico y secuencial y respondía con la ficha del cliente, con el UUID del recibo dentro. Esa segunda referencia directa convertía la extracción parcial en enumeración completa:

Pseudocódigo: de identificador secuencial a UUID
for customer_id in range(1, 100000):
    ficha = get(f"/[FUNCIONALIDAD]?id={customer_id}")
    if ficha.ok:
        uuid = ficha.json["receipt_uuid"]
        pdf  = get(f"/clientes/recibos/{uuid}")   # 200 OK

La cadena

Las tres piezas, en orden, describen el recorrido completo:

Cadena de explotación
1. URL archivadas por terceros ->  UUID de recibo validos, sin tocar el objetivo
2. IDOR con id secuencial      ->  UUID de cualquier cliente, uno a uno
3. Ruta del recibo sin authz   ->  PDF completo de cada cliente

Un identificador impredecible reduce la probabilidad de acertar, no sustituye a la comprobación de permisos. En cuanto ese identificador viaja dentro de una URL, deja de estar bajo tu control: queda en el historial del navegador, en la cabecera de referencia, en los registros de los intermediarios y en los archivos públicos de la web. A partir de ahí ya no es un secreto, y la ruta que dependía de él queda abierta.

Impacto

  • Lectura de los recibos de toda la cartera de clientes, sin autenticarse
  • Datos fiscales y de contacto expuestos: nombre, dirección, identificador tributario e importes
  • Enumeración completa por identificadores secuenciales de la funcionalidad secundaria
  • Direcciones conservadas por terceros, fuera del alcance de cualquier corrección hecha en el servidor
  • Brecha de confidencialidad con datos personales y económicos de terceros

Remediación

  • Autorización en cada ruta. Comprobar que la sesión que pide el recibo es la titular del documento, con UUID o sin él.
  • Identificadores que no viajen de más. No devolver el UUID del recibo en respuestas que no lo necesiten.
  • Enlaces de un solo uso. Si el documento se comparte, firmar el enlace y darle caducidad en lugar de dejarlo permanente.
  • Dar por pública toda URL compartida. Solicitar la retirada de las direcciones ya archivadas y asumir que las demás siguen ahí.
  • Autorización también en la funcionalidad secundaria. El IDOR con identificador secuencial era la mitad de la cadena.

Referencias

Más análisis

Las cadenas no salen de un escáner: salen de encadenar a mano lo que por separado parece menor

Cuéntanos qué activos quieres auditar. Respondemos en menos de 24 horas.

Solicitar auditoríaLlamar