本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
jsPDFにおけるPDF注入・DoS脆弱性(CVE-2024-24737等)の技術詳解と緊急対策
【脅威の概要と背景】
jsPDFのHTML変換機能において、入力値の検証不備によるプロトタイプ汚染やPDF注入、リソース枯渇(DoS)を招く深刻な脆弱性が確認されました。(2024年報告、順次修正対応中)
【攻撃シナリオの可視化】
攻撃者が悪意のあるペイロード(HTML/JavaScript)を、jsPDFを使用してPDF化するアプリケーションに送信した場合のプロセスを以下に示します。
graph TD
A["攻撃者"] -->|悪意のあるHTML/Object| B("アプリケーション入力")
B -->|サニタイズ不足のまま渡す| C{"jsPDFエンジン"}
C -->|プロトタイプ汚染| D["任意のプロパティ操作"]
C -->|正規表現処理のループ| E["ブラウザ/サーバのハング: DoS"]
C -->|PDF構文の挿入| F["PDF注入: 情報漏洩/フィッシング"]
D --> G["XSS実行/リモートコード実行の可能性"]
【安全な実装と設定】
jsPDFを利用する際、特にhtml()やaddHTML()メソッドにユーザー入力を渡す場合は、厳格なサニタイズが必須です。
1. 脆弱な実装例(アンチパターン)
ユーザーからの入力をそのままjsPDFの変換メソッドに渡しているケースです。
// 脆弱な例:外部入力をそのままPDF化
const doc = new jsPDF();
const userInput = request.body.htmlData; // 攻撃者が操作可能
doc.html(userInput, {
callback: function (doc) {
doc.save('output.pdf');
}
});
2. 安全な代替案
信頼できるサニタイズライブラリ(DOMPurify等)の併用と、最新版へのアップデートを組み合わせます。
// 安全な例:DOMPurifyによるクリーンアップと最新jsPDFの利用
import { jsPDF } from "jspdf";
import DOMPurify from "dompurify";
const doc = new jsPDF();
const rawInput = request.body.htmlData;
// 1. サニタイズ(スクリプトや不正な属性を削除)
const cleanHTML = DOMPurify.sanitize(rawInput, {
USE_PROFILES: { html: true },
FORBID_ATTR: ['onerror', 'onload', 'style'] // プロトタイプ汚染に繋がる属性を制限
});
// 2. jsPDF v2.5.2以降を使用
doc.html(cleanHTML, {
callback: function (doc) {
doc.save('secure_output.pdf');
},
// 3. 実行環境の制限(Node.js環境などの場合)
autoPaging: 'text'
});
【検出と緩和策】
EDR/SIEMでの検知ポイント:
WAF/IPSでの
__proto__やconstructorといったプロトタイプ汚染特有の文字列を含むリクエストの監視。クライアントサイドでの長時間スクリプト実行(CPUスパイク)の検知。
応急的な緩和策(Workaround):
入力の制限: PDF出力機能をログイン済みユーザーのみに制限し、入力可能な文字種・長さを最小限に絞る。
CSPの設定:
Content-Security-Policyを適切に設定し、PDF生成時の予期せぬインラインスクリプト実行を防ぐ。ライブラリの強制更新:
npm audit fixまたはyarn auditを実行し、jsPDFをv2.5.2以降(または最新の安定版)へ強制アップデートする。
【実務上の落とし穴】
表示崩れのリスク: DOMPurify等で厳格にサニタイズを行うと、インラインスタイルや複雑なCSSが削除され、出力されるPDFのレイアウトが崩れる可能性があります。
パフォーマンスの低下: 大規模なHTMLドキュメントをサニタイズ・変換する場合、クライアントのメモリ消費が急増し、脆弱性を突かれずとも可用性が低下する(自己DoS状態)懸念があります。
Node.js環境の特殊性: サーバーサイドでjsPDF(jsdom併用)を動かしている場合、脆弱性の影響がサーバープロセス全体に及ぶため、ブラウザ実行時よりもリスク評価を一段階引き上げる必要があります。
【まとめ】
組織として優先的に実施すべき3項目:
依存関係の確認:
package-lock.json等を確認し、jsPDFが最新版(v2.5.2以降)であることを確認する。サニタイズの徹底: 入力値に対して
DOMPurify等の定評あるライブラリが適用されているか、コードレビューを実施する。入力制限の実装: HTML入力の代わりに、構造化データ(JSON等)を受け取ってテンプレートエンジンでPDF化する設計への移行を検討する。
参考文献:

