Desbordamiento de entero en array /W de stream XRef
GHSA-w2hj-54mc-76r4 · Asignación de CVE pendiente
Resumen
Un desbordamiento de entero en el cálculo de la suma del array /W del stream de referencia cruzada permite a cualquier atacante sin autenticar crashear cualquier aplicación que use pdfcpu proporcionando un PDF creado a medida. El desbordamiento produce una longitud de entrada pequeña y positiva que pasa la comprobación de integridad módulo, tras lo cual lecturas de slices fuera de rango disparan un panic: runtime error: slice bounds out of range sin recuperar. El panic escapa a la API pública y mata el proceso anfitrión.
Impacto
- Denegación de Servicio — panic de runtime sin recuperar termina el proceso.
- Vector de ataque: red — PDF malicioso vía subida, adjunto de email, o cualquier pipeline de procesamiento.
- Sin autenticación requerida; interacción de usuario limitada a que la víctima procese el archivo.
- Ámbito: cualquier aplicación que embeba pdfcpu (CLI, servicios HTTP, librerías) y proyectos Go descendientes.
Causa Raíz
En pkg/pdfcpu/read.go, extractXRefTableEntriesFromXRefStream() calcula la longitud de entrada de referencia cruzada sumando tres valores controlados por el atacante del array /W sin comprobación de desbordamiento:
// pkg/pdfcpu/read.go:710
i1 := xsd.W[0]
i2 := xsd.W[1]
i3 := xsd.W[2]
xrefEntryLen := i1 + i2 + i3 // ← sin comprobación de desbordamiento
Los valores solo se validan para no-negatividad en el parseo (pkg/pdfcpu/model/parse.go). Cuando la suma desborda int64 a un valor positivo pequeño (p.ej. 1), la validación módulo pasa pero los valores W individuales permanecen enormes, por lo que las operaciones de slice posteriores leen mucho más allá del buffer:
// read.go:763-766 — bufToInt64(buf[i : i+i1]) con i1 ≈ 6.1e18
Prueba de Concepto
Crear un stream XRef cuyos valores /W desbordan al sumarse:
W = [6148914691236517205, 6148914691236517205, 6148914691236517207]
suma matemática: 18446744073709551617
desbordamiento int64: 1 → pasa comprobación módulo
slices reales: buf[i : i+6148914691236517205] → PANIC
Confirmado con una prueba unitaria contra la función vulnerable:
=== RUN TestXRefWArrayOverflow/overflow_to_one
PANIC: runtime error: slice bounds out of range
[:6148914691236517205] with capacity 3
Un PDF mínimo que incrusta tal stream XRef crashea pdfcpu validate, pdfcpu merge, y cualquier llamada api.ReadContext() sobre el archivo.
Cronología de Divulgación
| Fecha | Evento |
|---|---|
| 2026-09-13 | Informe enviado vía GitHub Private Vulnerability Reporting |
| 2026-09-14 | Aceptado por el mantenedor (hhrutter) |
| 2026-09-28 | Aviso publicado — GHSA-w2hj-54mc-76r4 |
| Corregido en | pdfcpu v0.16.0 |
Corrección
Usar safemath.AddInt existente del código para la suma del array W y rechazar desbordamientos:
// Después (seguro):
xrefEntryLen, err := safemath.AddInt(i1, i2)
if err != nil {
return errInvalidXRefStreamWArray
}
xrefEntryLen, err = safemath.AddInt(xrefEntryLen, i3)
if err != nil {
return errInvalidXRefStreamWArray
}
Corregido en pdfcpu v0.16.0. Aviso publicado 2026-09-28; asignación de CVE pendiente.