何が起きるか
パストラバーサルは、許可したフォルダ内のファイルだけを読む・書くはずの処理が、攻撃者の指定したパスによってその外のファイルを扱う問題です。
説明用に、ダウンロードAPIが保管領域/srv/uploadsへ、リクエストで受け取った../config.jsonを連結する場合を考えます。できた/srv/uploads/../config.jsonの..は一つ上のフォルダを指すため、OSが開く対象は/srv/config.jsonになります。アプリのOSユーザーがこのファイルを読め、APIが内容を応答へ返すなら、攻撃者は公開する予定のなかった設定情報を取得できます。パスの文字列に保管領域名が入っているだけでは、実際の対象を領域内に制限できません。
正常ならどう動くか
安全な構成の一例として、ダウンロードAPIが利用者の指定した公開IDを、サーバーで管理するファイルの固定パスへ対応付ける方式があります。サーバーはそのIDのファイルを読む権限も確認し、許可した場合だけファイルを開いてHTTPレスポンスに内容を入れます。ファイル名を受け付ける方式もありますが、その場合は解決した対象が許可領域内か確認します。
アーカイブを受信すると、展開処理は内部に記録された各ファイル名から保存先を作り、内容を書き出します。通常のアップロードも含め、受け取った名前を保管領域と組み合わせた後、実際に開く対象がその領域内にあることを確認します。OSユーザーの書き込み権限も保管領域へ制限しておけば、領域外のファイルへ書く要求をOS側でも拒否できます。
不備と攻撃が成立する流れ
説明用に、ダウンロード対象の保管領域を/srv/uploads、入力名を../config.jsonとします。アプリが両者を連結すると/srv/uploads/../config.jsonになります。OSが..を上位フォルダへの移動として解釈すると、開く対象は保管領域外の/srv/config.jsonです。
文字列に保管領域の名前が含まれていても、最終的に開くファイルを制限できていなければ不備が残ります。絶対パスや、別の場所を指すシンボリックリンクも同じ検討が必要です。検査後のデコードや区切り文字の変換で解決先が変わる場合もあり、検査した文字列と実際に開く対象を照合します。 たとえば%2e%2e%2fconfig.jsonを通常の名前として検査に通すとします。その後URLデコードで%2eを.、%2fを/へ変換すると、実際には../config.jsonを開く処理になります。検査した時点と使用する時点で文字列の意味が変わるのが問題です。
起こり得る被害と条件
読み取りの例では、アプリが領域外の設定ファイルを開き、その内容をダウンロードAPIのHTTPレスポンスで返します。攻撃者はレスポンスから接続パスワードなどを入手できます。アプリのOSユーザーがそのファイルを読めることと、内容を攻撃者へ返す経路が必要です。
書き込みの例では、アーカイブ内のファイル名を通じて領域外の設定ファイルへ書き込みます。その設定を後からアプリが採用すると、接続先などの動作を変えられるおそれがあります。コードを保存する場所へ書けても、そのファイルを後で実行する設定がなければ、直ちにコード実行が成立するわけではありません。
防ぎ方と、防げる理由
可能なら利用者がファイル名を指定する方式をやめ、公開IDをサーバーが持つ固定パスへ対応付けます。パスを受ける必要がある場合は、デコードや正規化を終え、..や区切り文字を解釈した最終的な保存先が許可領域内か、ディレクトリの境界も含めて確認します。/srv/uploadsで始まるという文字列判定だけでは、/srv/uploads-otherという別領域も通ってしまいます。
シンボリックリンクは、領域内の名前から領域外のファイルを指せます。実装するOSに応じて、リンクをたどらないファイルオープンや、基準ディレクトリから領域外へ移動できないオープン方法を使います。たとえば攻撃者が共有ディレクトリへリンクを作成・置換する権限を持つと、アプリが検査した後、開く前にリンク先を領域外へ変更できる場合があります。このような構成では、事前のパス検査だけに頼らず、開く瞬間にも制約を適用します。これらは一般的な設計上の対策で、個別製品の修正方法を示すものではありません。
よくある誤解
先頭がbaseであるかだけでは、base-otherのような別フォルダを区別できません。../を一度消すだけでも、別表記・後のデコード・リンクによる迂回が残る場合があります。
実装の確認点
ファイル取得、保存、アーカイブ展開、ビルド時のマウントで、誰がどのパスを指定するか確認します。名前の検査、デコード、リンク解決、ファイルを開く処理を順に追います。検査と使用の間に対象を差し替えられないか、読み取った内容がHTTPレスポンスなどで攻撃者へ届くかも調べます。 ビルド時のマウントとは、指定したホスト側のパスをビルド用コンテナから読めるよう共有する処理です。プロジェクトが指定するパスやリンクを追う際に許可領域外のホストファイルまで共有しないかも確認します。
出典・確認範囲
- [1] Web Security Academy: パストラバーサルPortSwigger / 確認日 2026-11-01