CERT/CCは2026年11月12日、ImageMagickを使うアプリケーションで任意のファイルを読み書きされる問題をVU#580079(通称ImageTragick2)として公開しました。原因はImageMagick本体のバグではなく、既定のまま、あるいはアプリが用意したpolicy.xmlが危険な読み込み方式を許していることです。この記事では、攻撃経路、対象かを確かめるコマンド、許可リスト方式のpolicy.xml、Rails・WordPressの状況、ポリシー以外の防御を、2026年11月14日時点の一次情報で整理します。
まとめ:policy.xmlを許可リストへ替え、画像変換を隔離して当日中に判定
当日中にやることは2つです。外部から受け取った画像をImageMagickに渡している箇所を洗い出すことと、その環境で有効なpolicy.xmlがMSL・MVG・PS・EPS・PDFを拒否しているかを確かめることです。ImageMagickを最新版に上げるだけでは足りません。
恒久対策は、必要な形式だけを通す許可リスト方式のポリシーへの書き換えです。そのうえで変換処理を権限とファイルシステムを絞った専用のコンテナへ分けます。Ruby on RailsとWordPressは修正版が出ているので、まず更新を当てます。
画像アップロードを持つシステムが複数あり、どこでImageMagickが動いているか把握しきれない場合は、脆弱性診断・セキュリティ診断でアップロード経路の棚卸しから始めると漏れが出にくくなります。
ImageTragick2の2つの経路:SVGからのMSL呼び出しとGhostscript
CERT/CCのVU#580079は、攻撃者が細工したSVGやPostScriptを処理させることで、ImageMagickのプロセスが触れるファイルを読み書きできると説明しています。条件次第では、書き込みとファイル読み取りの組み合わせによるコード実行も可能です。報告者はGMO Flatt SecurityのRyotaK氏で、2つ目の経路はpwn.aiのチームも独自に見つけています。日本ではJVNVU#95718857が11月13日に公開されましたが、詳細はCERT/CCの記載を参照する形です。
Variant 1:SVGのxlink:hrefからMSLスクリプトが動く仕組みと前提
細工したSVGの<image>要素で、xlink:hrefにMSL:のような危険なコーダーを指定します。するとImageMagickはその中身をMagick Scripting Language(MSL)のスクリプトとして解釈し、別の画像の読み込みや、攻撃者が指定したパスへの書き込みを行います。
成立の前提は、ImageMagick内部のSVGコーダーと、MSLなどの危険なコーダーの両方が使える状態であることです。拡張子を.pngにしていても、ImageMagickがファイルの中身からSVGと判定すれば同じ経路に入ります。
Variant 2:内容判定でGhostscriptが起動し一時領域を読み書き
ファイル名や申告された形式が別のものでも、中身がPostScriptと判定されるとImageMagickはGhostscriptを呼び出します。Ghostscriptは-dSAFER付きで起動しますが、CERT/CCが確認した構成では/tmpのファイル操作が許されていました。
一時ディレクトリを他の処理と共有するアプリでは、そこのセッションファイルや変換途中のデータが狙われます。WordPressで報告されたCVE-2026-65640はこの経路にあたります。
ImageMagick本体の欠陥ではなく設定の問題とされる理由と修正版の扱い
VU#580079は、独自のセキュリティポリシーで制限できる動作はImageMagick自体の脆弱性ではなく設定の問題として扱われる、と書いています。ポリシーを決めるのはアプリ側と配布元の責任という整理です。
ImageMagickの修正版という形の解決はありません。ImageMagickのリリース一覧の最新は2026年10月31日の7.1.2-35ですが、CERT/CCは更新だけでは危険なコーダーやデリゲートが許されたままの場合があると注意しています。版を上げる作業と、ポリシーを直す作業は別物として計画します。
自分の環境が対象か判定する手順:版・有効なポリシー・Ghostscriptの確認
判定は「ImageMagickを呼んでいるか」「どのポリシーが効いているか」「Ghostscriptが入っているか」の順に進めます。コンテナのアプリはコンテナの中で確かめます。
magickとconvertで版と有効なポリシーを一覧表示する確認コマンド
# ImageMagick 7系
magick -version
magick -list policy
# ImageMagick 6系(Ubuntu 22.04などの標準パッケージ)
convert -version
convert -list policy
# Ghostscriptが入っているか(Variant 2の前提)
gs --version
# 主要な形式の読み書き可否(rw-なら読める)
magick -list format | grep -E "^ *(MSL|MVG|PS|EPS|PDF|SVG|XPS)\*? "
-list policyの出力にPath:として読み込まれたファイルが表示されます。何も規則が出ないか、拒否の規則が数行しか無ければ、動作中の設定は既定の緩いポリシーです。RailsのGHSA-f3w6-w445-fwh9は、DebianとUbuntuが配るポリシーでは問題のコーダーが拒否されていないと明記しています。上のコマンドはImageMagickの標準オプションで、私たちは今回の判定には実行していません。
MSLやPostScriptの読み込みが実際に拒否されるか無害なファイルで試す方法
規則が書いてあっても、後ろの行で上書きされて効いていないことがあります。中身だけPostScriptにした無害なファイルを、拡張子を偽って読ませるのが手早い確認です。
# 中身はPostScript、拡張子はpng(攻撃コードは含まない)
printf '%%!PS\nshowpage\n' > policy_check.png
# 拒否できていれば security policy に関するエラーで止まる
magick identify policy_check.png
# 1行ずつ効いているか確かめるときはデバッグ出力を使う
magick -debug policy identify policy_check.png 2>&1 | tail -n 20
画像の情報が表示されたら、PostScriptがGhostscriptへ渡っています。試験は、環境変数の差で結果が変わるため、アプリと同じユーザー・同じ環境変数で行います。
PHPのImagickやPythonのWandなど言語別の呼び出し経路
コードにmagickの文字が無くても、ライブラリ経由で呼んでいることがあります。
| 言語・製品 | ライブラリ | 呼び出し方 | VU#580079の対象 |
|---|---|---|---|
| PHP・WordPress | Imagick拡張 | MagickWandをリンク | 対象(システムのポリシーを読む) |
| Python | Wand | MagickWandをctypesで呼ぶ | 対象 |
| Ruby・Rails | mini_magick | CLIを起動 | 対象(Railsは修正版あり) |
| Node.js | gm・imagemagick | CLIを起動 | ImageMagickモード時は対象 |
| Python | Pillow | 独自のデコーダー | 対象外(別ライブラリ) |
| Node.js | sharp | libvips | 対象外(別ライブラリ) |
PHPならphp -r 'print_r(Imagick::getVersion());'、Wandならpython -c "import wand.version as v; print(v.MAGICK_VERSION)"で、リンクしているImageMagickの版が分かります。Pillowは今回の対象外ですが、デコーダー自体の脆弱性は別に出ています。修正状況はPillowの脆弱性43件と13.0.0への更新手順で確かめてください。
policy.xmlを許可リスト方式に書き換える設定例:Web公開アプリ向け
CERT/CCが勧めるのは、危険な形式を1つずつ拒否する方式ではなく、必要な形式と操作だけを有効にする許可リスト方式です。同梱のテンプレートでは不十分な場合があるとも書いており、書いたあとに拒否されることの検証まで求めています。
全コーダーを拒否しJPEG・PNG・GIF・WebPだけを許可するpolicy.xml
ユーザーの画像をサムネイルにするだけのWebアプリなら、次の形が出発点になります。ImageMagick公式のSecurity Policyが示す公開サイト向けのwebsafeポリシーと同じ考え方で、外部デリゲート・フィルター・間接読み込みを止め、読み書きできる形式を4つに絞ります。
<?xml version="1.0" encoding="UTF-8"?>
<policymap>
<!-- 資源の上限(巨大画像によるDoS対策) -->
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="width" value="8KP"/>
<policy domain="resource" name="height" value="8KP"/>
<policy domain="resource" name="time" value="60"/>
<!-- Ghostscript・ffmpegなど外部デリゲートを全部止める -->
<policy domain="delegate" rights="none" pattern="*"/>
<policy domain="filter" rights="none" pattern="*"/>
<!-- @file形式の間接読み込みと/etc配下を拒否 -->
<policy domain="path" rights="none" pattern="@*"/>
<policy domain="path" rights="none" pattern="/etc/*"/>
<!-- まず全コーダーを拒否し、後ろで必要な形式だけ許可する -->
<policy domain="module" rights="none" pattern="{MSL,MVG,PS,PDF,SVG,URL,XPS}"/>
<policy domain="coder" rights="none" pattern="*"/>
<policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}"/>
<policy domain="system" name="filename:literal" value="true"/>
</policymap>
このポリシーでは、PDFのサムネイルやSVGの書き出しは使えなくなります。それらが業務上必要なら、同じサーバーで許可するのではなく、後述の隔離した変換専用の環境へ分けます。上の設定は公式の記載をもとに書いたもので、私たちは未実行です。適用後は前の章の確認コマンドで、JPEGが変換でき、PostScriptが拒否されることを両方確かめてください。
MAGICK_CONFIGURE_PATHでアプリ専用のポリシーを読ませる方法と探索順
システムのpolicy.xmlを書き換えると、同じサーバーの他のアプリにも効きます。アプリだけに効かせたい場合に使うのは、環境変数MAGICK_CONFIGURE_PATHです。ImageMagick公式のResourcesによると、この変数で指定した場所は既定の場所より先に探されます。Linuxの探索順は次のとおりです。
$MAGICK_CONFIGURE_PATH$PREFIX/etc/ImageMagick-7$PREFIX/share/ImageMagick-7$XDG_CACHE_HOME/ImageMagick$HOME/.config/ImageMagick<client path>/etc/ImageMagick
注意点は、変数がプロセスに渡っていないと黙って既定の場所に落ちることです。PHP-FPMならプール設定のenv[]、systemdのサービスならEnvironment=で渡し、ワーカーの中から-list policyのPath:を見て確かめます。
7.1.1-16より前で大文字小文字を区別するglobと後勝ちの落とし穴
公式ページによると、7.1.1-16より前の版ではポリシーのglobが大文字小文字を区別します。pattern="eps"と小文字で書いてもEPSには当たらないため、コーダー名は大文字で書きます。Ubuntu 22.04の標準パッケージは6.9系なので、この古い挙動の側です。
規則の並び順も効きます。公式ページが示しているのは、広い拒否を先に置き、例外の許可を後ろに置くという順序です。coderの"*"拒否を許可の行より後ろに書くと、許可した形式まで拒否されます。逆に、古いテンプレートの末尾にrights="read | write" pattern="*"のような行が残っていると、前の拒否が打ち消されます。
影響ありと公表された製品の対応状況:Rails・WordPress・Kiteworks
VU#580079のベンダー情報(2026年11月12日版)では、ステータスは次のとおりです。Unknownは「影響なし」ではなく、CERT/CCが声明を受け取っていないという意味です。
| ベンダー | ステータス | 内容 |
|---|---|---|
| Ruby on Rails | Affected | 8.0.5.2・8.1.4.1でポリシーを同梱 |
| Kiteworks | Affected | ownCloud Classic含め修正中 |
| Wikimedia(MediaWiki) | Not Affected | ベンダー声明は未受領 |
| WordPress | Unknown | Variant 2でCVE-2026-65640 |
| Debian・Ubuntu | Unknown | 声明未受領 |
| Red Hat・Redmine | Unknown | 声明未受領 |
DebianやUbuntuの標準パッケージを使う環境は、配布元の対応を待たずにアプリ側でポリシーを入れます。
Rails 8.1.4.1・8.0.5.2が同梱したmini_magick向けポリシー
Railsは2026年11月4日の8.1.4.1・8.0.5.2で、Active Storageがmini_magickを呼ぶときに使うpolicy.xmlを同梱しました。GHSA-f3w6-w445-fwh9はCVE-2026-126082、CVSS 9.8のCriticalで、更新できない場合にシステムへ写す最低限の3行として、MSLコーダーの拒否、Ghostscriptデリゲート(gs)の拒否、PS・EPS・PDF・XPSなど19形式の拒否を挙げています。
この3行は拒否リスト方式なので、前の章の許可リストより守れる範囲が狭くなります。Rails以外のアプリと同じサーバーにある場合は、許可リストをシステム側に入れる方が安全です。Railsでの判定コマンド、secret_key_baseを入れ替える条件はRailsの脆弱性21件とActive Storageの回避策で詳しく扱っています。
WordPress 7.0.4で直ったCVE-2026-65640とプラグインに残る範囲
WordPress 7.0.4のリリース告知(2026年8月12日)によると、修正したのはImagickとGhostscriptを使うサイトで、投稿者(Author)以上の権限を持つ利用者が細工したファイルのアップロードからリモートコードを実行できる問題です。4.7系以降の古いブランチにも修正版が配られました。
独自にImagickへファイルを渡すフォームプラグインなどは、コアを更新しても同じ判定のずれを抱えたままになりえます。サーバーのpolicy.xmlでPS・EPS・PDFを拒否しておけば、どのプラグイン経由でもGhostscriptまで届きません。
policy.xmlだけに頼らない多層化:コンテナ隔離・中身判定・監視
CERT/CCは、ポリシーに加えて、信頼できない画像を権限とファイルシステムを絞った専用の環境で処理することを求めています。ポリシーの書き漏れや、ポリシーそのものを回避する不具合が後から見つかっても、被害をそのコンテナの中に留めるためです。
画像変換を別コンテナに分け読み取り専用と/tmp分離で被害範囲を絞る
# ネットワーク無し・ルートFS読み取り専用・/tmpは専用のtmpfs
docker run --rm \
--network none \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m \
--user 65534:65534 \
--cap-drop ALL \
-e MAGICK_CONFIGURE_PATH=/etc/imagemagick-app \
-v "$PWD/policy:/etc/imagemagick-app:ro" \
-v "$PWD/in:/in:ro" \
-v "$PWD/out:/out" \
imagemagick-worker:7.1.2-35 \
magick png:/in/upload.bin -resize 1024x1024 png:/out/thumb.png
効いているのは、Variant 2が狙う/tmpをアプリ本体と共有しないこと、書き込み先を/outだけにすること、MSLなどで外部URLを読みに行けないようネットワークを切ることの3点です。外部URLの取得はSSRFの入口にもなります。経路の考え方はSSRFの仕組みと防御実装で確かめられます。コンテナの中にアプリの秘密情報や書き込み可能なホストのマウントを置かないことも条件です。imagemagick-workerは自前でビルドする想定のイメージ名で、私たちはこのコマンドを未実行です。
隔離はカーネルの脆弱性を突かれれば抜けられるので、ポリシーの代わりにはなりません。方式ごとの限界はサンドボックスの仕組みと限界で整理しています。
拡張子でなくマジックバイトで形式を判定し形式を明示して渡す実装例
CERT/CCは、ファイル名・拡張子・クライアントが申告したメディアタイプではなく、中身で形式を検証するよう求めています。中身を先頭バイトで判定し、判定した形式をImageMagickへ明示して渡せば、ImageMagickが勝手にPostScriptやSVGと判定する余地を減らせます。
import subprocess
SIGNATURES = [
(b"\xff\xd8\xff", "jpeg"),
(b"\x89PNG\r\n\x1a\n", "png"),
(b"GIF87a", "gif"),
(b"GIF89a", "gif"),
]
def sniff(path: str) -> str | None:
with open(path, "rb") as f:
head = f.read(16)
for sig, kind in SIGNATURES:
if head.startswith(sig):
return kind
if head[:4] == b"RIFF" and head[8:12] == b"WEBP":
return "webp"
return None # 許可していない形式は変換に回さない
def make_thumb(src: str, dst: str) -> None:
kind = sniff(src)
if kind is None:
raise ValueError("unsupported image format")
# 引数は配列で渡し、入力側に形式の接頭辞を付けて自動判定を止める
subprocess.run(
["magick", f"{kind}:{src}", "-resize", "1024x1024", f"png:{dst}"],
check=True, timeout=60,
)
引数を文字列連結せず配列で渡しているのは、ファイル名経由のコマンド注入を避けるためです。理由はOSコマンドインジェクションを引数配列で防ぐ実装で解説しています。監視では、ImageMagickのポリシー違反のエラー、想定外のコーダーやデリゲートの起動、変換の異常終了、出力先以外に増えたファイルを拾って通知します。上のコードは考え方を示すための例で、私たちは未実行です。
対応の優先順位と判断:当日やることと置き換えを見送ってよい環境
誰が画像を送れるかで順番を決めます。
認証なしでアップロードを受けるアプリを最優先にする理由と順番
最優先は、会員登録前の問い合わせフォームや求人応募フォームのように、誰でもファイルを送れて、その場でサムネイルを作るアプリです。RailsのCriticalも、認証なしで添付1回で成立すると書かれています。次がWordPressのように投稿者以上に限られる経路、最後が社内の担当者だけが画像を扱う管理画面です。
最優先のアプリでは、ポリシーを入れた日に/tmpと変換結果の置き場に覚えのないファイルが無いかも確かめます。読み取りは痕跡が残りにくいため、アプリのプロセスが読めた認証情報は入れ替えの対象です。トークンの失効手順はAPI不正アクセス対策の実装手順にまとめています。
libvipsやPillowへの置き換えを選ぶ条件と置き換えを見送る場面
私たちの判断は次のとおりです。扱う形式がJPEG・PNG・GIF・WebPだけで、PDFやSVGの変換が要らないアプリは、ImageMagickをやめてlibvips(Railsなら:vips、Node.jsならsharp)やPillowへ置き換えます。危険なコーダーを持たない分、ポリシーの書き漏れを心配する範囲が減るからです。
見送ってよいのは、PDFのサムネイルや多様な形式の変換が業務の中心にあるアプリです。置き換え先では同じ機能が揃わず、結局Ghostscriptを別途呼ぶことになります。この場合に選ぶ運用方法は、ImageMagickを残し、許可リストのポリシーと隔離したコンテナを使う形です。どちらでも、ライブラリの更新を定期作業に組み込みます。仕組みづくりはパッチ管理の手順を参考にしてください。
ImageMagickの脆弱性VU#580079の対応でよく受ける質問と回答
判定と設定の作業中に出やすい疑問に、2026年11月14日時点の一次情報の範囲で答えます。
ImageMagickを最新版に上げれば今回の問題は直りますか?
それだけでは直りません。VU#580079は、ポリシーで制限できる動作を設定の問題として扱っており、ImageMagickの修正版で閉じる形にはなっていません。CERT/CCも、更新しても危険なコーダーやデリゲートが許されたままなら不十分だと書いています。最新版(2026年10月31日時点で7.1.2-35)への更新は他の脆弱性のために行い、それとは別にpolicy.xmlを許可リスト方式へ書き換えてください。
2016年のImageTragickとは何が違いますか?
2016年のImageTragick(CVE-2016-3714など)は、外部デリゲートへのコマンド注入でコードを実行できる問題で、ImageMagick側の修正とポリシーの両方で対処されました。今回は、既定の緩いポリシーのもとでMSLスクリプトやGhostscriptの/tmpアクセスを使い、ファイルを読み書きする問題です。2016年に入れた拒否リストのポリシーにはPSやEPSが含まれていないことがあり、当時のままの環境ほど見直しが要ります。
GraphicsMagickやlibvipsを使っている場合も対象ですか?
VU#580079の対象はImageMagickベースのアプリで、GraphicsMagickとlibvipsはベンダー情報に載っていません。ただしRailsのGHSAは、GraphicsMagickはImageMagickのポリシーを読まないのでpolicy.xmlの設定が効かないと書いています。GraphicsMagickでPostScriptを扱うなら、Ghostscriptを入れない、または変換を隔離するといった別の手段で守ります。
CVE番号は振られていますか?脆弱性管理ツールで検知できますか?
VU#580079とJVNVU#95718857のページ自体にはCVE番号の記載がありません。個別の製品では、WordPressの経路がCVE-2026-65640、RailsのActive StorageがCVE-2026-126082です。パッケージの版を見るだけの管理ツールではポリシーの緩さを検知できないため、-list policyの結果をサーバーの点検項目に加えてください。
実際に悪用されているかはどこで確かめられますか?
2026年11月14日時点で、CERT/CCのVU#580079に悪用を確認したという記載はなく、Kiteworksは自社製品について悪用の兆候は無いと回答しています。悪用の有無は米CISAのKEVカタログとCERT/CCのページの更新で追います。ファイル1枚で成立する経路もあるので、報告を待たずにポリシーを入れてください。
関連記事
- Railsの脆弱性21件:8.1.4.1・8.0.5.2の修正内容とActive Storageの回避策:Active Storage経由のImageMagick問題と、秘密情報の入れ替え判断です。
- Pillow 脆弱性:CVE-2026-96639ほか13.0.0で直った43件の確認とPython 3.10の更新手順:ImageMagickから置き換えたあとに追うPython画像ライブラリ側の脆弱性です。
- OSコマンドインジェクションとは?仕組みと引数配列で防ぐ実装をPython・Node.js・Goのコード例で解説:CLIを外部コマンドとして呼ぶときの安全な書き方です。
- Webシェルとは?仕組み・代表例と検知・除去の手順をTomcat・PHP・IISのコマンド例で解説:ファイル書き込みを許したあとに置かれやすいWebシェルの見つけ方です。
- 脆弱性診断とは?種類・費用相場・進め方と外注時の判断基準を解説:アップロード経路の棚卸しを外部に頼むときの判断材料です。