TeX システムの「外部コマンド実行設定」に関するセキュリティホールが報告されている。
既に W32TeX や TeX Live(本家)の側での対策は行われている。ユーザが「TeX システムをアップデートする」などの対策をとる必要がある。
内容
- TeX 処理系にはもともと「外部のソフトウェア(コマンド)」を実行する機能があるが、安全のため、既定では実行できる外部のコマンドを特定のもの(kpsewhich 等)に制限している。この状態を「制限付シェルエスケープ(restricted shell escape)」という。
- しかしこの脆弱性のためその制限が実質的に無効になる。
- つまり攻撃者が任意の外部コマンドを(ユーザの権限で)実行できるようになる。
影響範囲
以下の事項の全てを満たす場合に影響を受ける。
- 2010 年頃以降にインストールされた TeX 配布。
(※恐らくそのほとんど全てが該当する。) - 「制限付シェルエスケープ」の状態で使用している、またはその可能性がある。
(※それが既定なので、ほとんどの人が該当する。) - 「制限付シェルエスケープ」での実行が許された外部コマンドの中に MetaPost のコマンド(mpost、jmpost、pmpost、upmpost)が含まれている。以後この状態を【無制限 MetaPost 連携可能】と呼ぶことにする。
以下の事項は関係しない。
- エンジン(TeX、pTeX、LuaTeX、…)の種類。
- フォーマット(plain TeX、LaTeX、…)の種類。*1
- 自分が MetaPost を使う(自分で起動する)ことがあるか。
- TeX 配布の新しさ。
- たとえ(この記事から見て)未来のもの(例えば“2017 年の最新版”)でも、ユーザの設定によっては【無制限 MetaPost 連携可能】になる可能性がある。*2
検査方法
【無制限 MetaPost 連携可能】であるかを調べる方法。
- コマンドシェルで以下のコマンドを実行する。
kpsewhich -var-value=shell_escape_commands
- 次のようなコマンド名のリストが表示されるはずである。
(※これが「実行が許可された外部コマンド」のリストである。)
(※何も表示されないならば【無制限 MetaPost 連携可能】ではない。*3)bibtex,bibtex8,extractbb,kpsewhich,makeindex,mpost,repstopdf
- リストの中に mpost、jmpost、pmpost、upmpost のいずれか が存在すれば【無制限 MetaPost 連携可能】である。
- rmpost、rpmpost のように r で始まる名前のものは関係しない。*4
対処方法
- 可能であれば TeX 配布を最新版にアップデートする。
(※最新版では「実行が許可された外部コマンド」から MetaPost のコマンドを除外する修正がされている。しかしユーザ側でカスタムの設定がなされている場合は修正が反映されない可能性がある。) - アップデートした場合、再度上記の検査を行う。【無制限 MetaPost 連携可能】でない状態になっていればOK。
- まだ【無制限 MetaPost 連携可能】である場合、「MetaPost のコマンドを、『実行が許可された外部コマンド』のリストから外す」処置を行う。
- TeX Live本家など、tlmgrコマンドが利用できる場合は、以下のコマンドを実行する。
tlmgr conf texmf shell_escape_commands 「リスト」
ここで「リスト」の部分は、検査の際に kpsewhich コマンドにより表示された「実行が許可された外部コマンド」のリストのうち、mpost、jmpost、pmpost、upmpost を(あれば)除外したものを指定する。
(※例えば検査の箇所で示した例の場合は「リスト」はbibtex,bibtex8,extractbb,kpsewhich,makeindex,repstopdf
である。)
- TeX Live本家など、tlmgrコマンドが利用できる場合は、以下のコマンドを実行する。
- tlmgrが利用できない場合は、以下の手順を行う。
- 以下のコマンドを実行して、有効なtexmf.cnfファイルを探す。
kpsewhich texmf.cnf
ここで表示されるパス名が有効なtexmf.cnfである。
- 有効なtexmf.cnfファイルの中に「
shell_escape_commands=
」で始まる行がある場合は、「=」の後にあるコマンド名のリスト((ここで、行末の「\
」は行継続を表す。すなわち、その「\
」が無くてかつ次の行と繋がっているのと同じと見なされる。))(「実行が許可された外部コマンド」と一致するはずである)から mpost、jmpost、pmpost、upmpost を(あれば)削除する。 - 「
shell_escape_commands=
」で始まる行がない場合は、適当な位置(例えば末尾)に以下の行を書き込む。shell_escape_commands=「リスト」
ここで「リスト」の部分は、「実行が許可された外部コマンド」のリストのうち、mpost、jmpost、pmpost、upmpost を(あれば)除外したものを指定する。
補足
- 今回の件は“攻撃者が構成したMetaPostのコマンド行”が原因となっている。自分でMetaPostのコマンドを実行する分には何の問題もない。