← ブログに戻る
7 novembre 2026 · 1 min 読了時間

exarch:私たちが報告したシンボリックリンクの脆弱性

GHSA-9r5q-fvpf-p55p:TAR や ZIP のアーカイブが、展開先に既に存在するシンボリックリンクを悪用して、展開フォルダの外にファイルを書き込めてしまう問題。Webcracy の Liam Giannini が見つけた内容と、exarch を 0.8.0 以降に更新すべき理由。

サイバーセキュリティexarchRustPythonNode.js脆弱性開示
脆弱性の概要図:TAR または ZIP のアーカイブ、展開先に既に存在するシンボリックリンク、展開フォルダの外に書き込まれるファイル

アーカイブの展開は、世の中で最も無害な操作のように見えます。フォルダを選び、ZIP を開けば、ファイルはそこに置かれる。しかし、アーカイブが外部から来る場合、つまりユーザーがアップロードしたもの、外部サービスからダウンロードしたもの、メールに添付されたものである場合、ファイルが どこに 書き込まれるかはセキュリティの問題になります。巧妙に細工されたアーカイブは、選んだフォルダの外に書き込もうとすることがあります。設定ファイルへ、サーバーが起動時に実行するスクリプトへ、別のユーザーのフォルダへ。

exarch は、まさにそれを防ぐために作られたライブラリです。コアは Rust で書かれており(exarch-core)、Python パッケージ(exarch)と Node.js パッケージ(exarch-rs)としても配布されています。README では、Python の tarfile や Node.js の tar-fs といったライブラリの安全な代替として紹介されています。これらのライブラリには、まさにこの種の脆弱性の長い歴史があります。exarch の中心的な約束はただ一つ、アーカイブ内のファイルは展開先フォルダの中にとどまる、ということです。

バージョン 0.6.1 から 0.8.0 未満までは、この約束を回避することができました。これがアドバイザリ GHSA-9r5q-fvpf-p55p に記載された欠陥で、2026年11月2日に公開され、exarch 0.8.0 で修正されました。報告したのは私たちです。発見者は Liam Giannini(GitHub の Liam-G)、エシカルハッカーであり Webcracy の共同創業者です。問題を確認し、数日で修正をリリースしてくれた exarch のメンテナーに感謝します。

Webcracy とサイバーセキュリティ

Webcracy が手がけるのはウェブサイトやアプリケーションだけではありません。サイバーセキュリティは私たちの仕事の中心的な部分です。ペネトレーションテスト、コードレビュー、設定の分析、そして私たちやクライアントが日々使っているオープンソースのライブラリやプログラムの調査。Liam はエシカルハッカーとして働いています。攻撃者と同じ手法で欠陥を探しますが、目的は正反対です。見つけたものは修正できる相手に非公開で報告し、修正が利用可能になってから初めて公開します。このプロセスは 責任ある開示 と呼ばれ、10月に報告した FreeScout の脆弱性 と同様、今回もこの手順に従いました。

展開中に何が起きていたか

問題を理解するには、二つの要素が必要です。

一つ目は シンボリックリンク です。ファイルシステム上でフォルダのように振る舞いながら、実際には別の場所を指しているエントリです。デフォルト設定の exarch は、アーカイブに含まれる シンボリックリンクを拒否します。これは悪意のあるアーカイブに対する古典的な防御の一つです。しかし、別のケースは考慮されていませんでした。展開が始まる前から 展開先フォルダに 既に存在するシンボリックリンクです。これは思っているより頻繁に起こります。共有フォルダ、既存のインストールの上に展開されるアップデート、uploads や cache が別のディスクを指している環境などです。

二つ目は 作成済みフォルダのキャッシュ です。ファイルごとに同じチェックを繰り返さないよう、exarch は展開中に既に作成したフォルダを記憶し、それらを信頼できるものとして扱っていました。問題は、フォルダの作成に使われる Rust の関数 create_dir_all が、パスが既に存在していてそれがフォルダへのシンボリックリンクである場合にも成功を返すことです。そのため exarch は、実際には別の場所につながっているリンクを「自分が作成したフォルダ」として記録していました。

攻撃者に必要なのは、ごく普通の二つのエントリを含むアーカイブだけでした。フォルダ redirect/ と、ファイル redirect/pwned.txt です。展開先に redirect が書き込み可能な外部フォルダへのリンクとして既に存在していれば、一つ目のエントリによってそのリンクが信頼済みフォルダのキャッシュに入ります。二つ目のエントリを検証する際、exarch は親パスの解決を省略していました。信頼済みだからです。さらに完全なパスの解決も省略していました。アーカイブにシンボリックリンクが含まれていなかったからです。ファイルを開く際に使われる O_NOFOLLOW フラグが保護するのはパスの最後の要素だけで、途中のフォルダは対象外です。結果として、展開は正常に完了し、ファイルは選んだフォルダの外の outside/pwned.txt に、アーカイブを用意した人物が決めた内容で現れました。

この問題は、デフォルトのセキュリティ設定で TAR と ZIP の両方に影響していました。一方、7z ファイルの展開は脆弱ではありませんでした。設計上、パスの検証にフォルダキャッシュを使っていなかったためです。

どの程度深刻か

実際の影響は、アプリケーションがどこで動いているかによります。最悪の場合、プロセスの権限だけを上限とする 展開先の外への任意のファイル書き込み になります。上書きを許可する skip_duplicates = false オプションを使っていれば、リンク経由で到達できる既存ファイルが切り詰められたり置き換えられたりする可能性もありました。そこから、設定の改ざん、攻撃者による永続化、サービスの停止、あるいは書き込まれたファイルが後で別のコンポーネントに読み込まれたり実行されたりした場合のコード実行につながり得ます。

ただし、必要条件があります。シンボリックリンクが既に展開先に存在し、攻撃者がその名前を知っている必要があります。そのため深刻度は中程度で、カテゴリは CWE-59(ファイルアクセス前のリンク解決の不備)です。とはいえ、中程度だからといって些細な問題ではありません。この欠陥は、exarch のようなライブラリを選ぶ唯一の理由である保証そのものを損なうものです。

どのように検証したか

問題は exarch 0.6.1 のソースコードを読む中で見つかりました。アーカイブのエントリがフォルダキャッシュ(DirCache)から SafePath での検証、そして最終的なファイルのオープンに至るまでの経路をたどったのです。確認のため、Liam は TAR 用と ZIP 用に一つずつ、二つの回帰テストを書きました。どちらもアーカイブをメモリ上で構築し、専用に作成した一時フォルダに展開するもので、環境は Linux と Rust 1.98.0 です。脆弱なバージョンでは、展開が成功してファイルが展開先の外に出てしまうため、両方のテストが失敗しました。

報告と合わせて、最小限の修正も用意しました。TAR と ZIP の検証において、キャッシュに含まれていることを安全の証拠として使うのをやめ、7z のコードが既に行っていた方式に揃えるというものです。この変更により二つの回帰テストは成功し、既存の 801 件のユニットテストと 136 件の統合テストもすべて成功しました。

0.8.0 での修正

メンテナーは最小限のパッチ以上のことをしてくれました。バージョン 0.8.0 に含まれる プルリクエスト #816 では、キャッシュが削除され、書き込むファイルごとに展開先以下のパスの各要素を lstat で調べるチェックに置き換えられました。親パスは、展開先のルートと一致する場合を除き、毎回解決されます。この修正は TAR、ZIP、7z のすべてに適用され、アトミック展開モードも含まれます。

知っておくべき動作の変更が一つあります。デフォルトでは、展開先にシンボリックリンクが一つでもあると展開が失敗する ようになりました。展開先の内部を指すリンクであっても同様です。必要な場合はシンボリックリンク用のオプションで再び有効にできますが、その場合も展開先フォルダの内部にとどまるリンクだけが受け入れられます。シンボリックリンクそのものを展開先フォルダとして使うことは引き続き許可されています。

プルリクエストでは、残る制限についても率直に述べられていました。パスに基づくチェックでは、検証と書き込みの間に時間的な隙間が残り、展開中に既に展開先への書き込み権限を持つ者がそれを悪用できる、という点です。11月5日にリリースされた バージョン 0.9.0 には、他の変更とともに、書き込みをディレクトリディスクリプタに固定する仕組みが含まれています。これはそのケースに対して推奨される解決策です。一つの報告が、単一の穴をふさぐだけでなく、サブシステム全体を強化するきっかけになり得ることを示す、とても良い例です。

exarch を使っている場合にすべきこと

exarch-core、Python パッケージ exarch、npm パッケージ exarch-rs のいずれかを 0.8.0 より前のバージョンで使っているなら、アップデートしてください。0.9.0 ではファイル書き込みに関する保護がさらに追加されているため、リリースノートに記載された互換性のない API 変更を確認したうえで、最新バージョンに直接上げるのがよいでしょう。アップデート後は、展開先にある正当なシンボリックリンクのせいで展開が失敗していないかも確認してください。これが新しいデフォルトの動作であり、最も安全なのは空の専用フォルダに展開することです。

もっとも、このアドバイスは exarch に限らず、あらゆる展開ライブラリに当てはまります。外部から来たアーカイブは、自分のプロセスが新たに作成した空のフォルダに、必要最小限の権限しか持たないユーザーで展開してください。そうすれば、今回のような欠陥があっても、悪用できるリンクが最初から用意されていることはありません。

なぜオープンソースソフトウェアを調査するのか

企業で動いているソフトウェアの大部分は、使っていないと思っている企業も含め、exarch のようなオープンソースライブラリでできており、多くの場合たった一人か小さなグループによって保守されています。コードは公開されていますが、誰かがそれを壊そうとする者の目で読まなければなりません。こうしたプロジェクトのレビューに時間を割き、見つけたものを責任をもって報告することが、私たちなりの貢献の仕方であり、クライアントのために本番環境に何を投入しているのかを正確に把握する方法でもあります。

あなたのアプリケーションがユーザーのアップロードしたファイルを受け付けている、外部からのアーカイブ、文書、画像を処理している、あるいは単に欠陥を探す人の目で一度も見られたことがない、という場合は、ぜひご相談ください。私たちの ペネトレーションテスト の仕事は、まさにここから始まります。コードと設定を読み、どこでデータがチェックされていないかを把握し、何を検証して何を検証していないかを正確にお伝えします。

アプリケーションのセキュリティについて相談する

プロジェクトをお持ちですか?

カスタムデジタルソリューションでビジネスをサポートする方法についてご相談ください。

お問い合わせ