ディレクトリトラバーサルとは?攻撃の仕組みと見落とされがちな対策の盲点

Webサービスを運営していると、「うちは小さいサイトだから狙われない」という油断が生まれがちです。しかしディレクトリトラバーサル攻撃は、規模の大小を問わず、ファイルパスを扱うすべてのWebアプリケーションが潜在的な標的になり得ます。
実際、IPAが公開している「安全なウェブサイトの作り方」でも、ディレクトリトラバーサルはSQLインジェクションやクロスサイトスクリプティングと並ぶ主要な脆弱性として取り上げられており、長年にわたって届出件数が絶えない攻撃手法のひとつです。
この記事では、ディレクトリトラバーサルの仕組みを基礎から整理したうえで、多くの解説記事では触れられていない「対策の落とし穴」まで踏み込んで解説します。セキュリティ担当者はもちろん、開発に携わるエンジニアにとっても実践的な内容になっています。
ディレクトリトラバーサルとは
ディレクトリトラバーサル(Directory Traversal)とは、Webアプリケーションが外部からの入力をもとにサーバー上のファイルを読み込む処理を悪用し、本来アクセスを想定していないディレクトリやファイルに不正アクセスする攻撃手法です。「パストラバーサル(Path Traversal)」とも呼ばれます。
攻撃自体はシンプルです。しかし、被害は深刻になります。設定ファイルやパスワードファイルが外部に漏洩したり、最悪の場合はシステムファイルを書き換えてサーバーを乗っ取られたりするケースもあります。
重要なのは、これが「高度なハッキング技術」を要する攻撃ではないという点です。攻撃に必要なのは、ブラウザとURLの書き換えだけであることが多く、攻撃ツールを使えば自動的にスキャンできます。つまり、経験の浅い攻撃者でも実行できるという意味で、脅威の裾野が広い攻撃手法です。
ディレクトリとパスの基本
攻撃の仕組みを理解するには、ファイルシステムの基本を押さえておく必要があります。
絶対パスは、ファイルシステムの最上位(ルートディレクトリ)から始まるパスです。Linuxであれば /var/www/html/index.html のように、常に / から記述します。どの位置からアクセスしても同じファイルを指します。
相対パスは、現在いる位置を起点にしたパスです。../ は「一つ上のディレクトリへ移動する」という意味を持ちます。たとえば /var/www/html/ にいる状態で ../../etc/passwd と指定すると、/etc/passwd にアクセスできます。
ディレクトリトラバーサル攻撃は、この ../ の連鎖を意図的に使って、Webサーバーの公開ディレクトリ(ドキュメントルート)の外側にあるファイルへ到達しようとするものです。「なぜドキュメントルートの外に出られるのか」と疑問に思う方もいるかもしれませんが、アプリケーションがパスを検証せずにそのままOSに渡してしまうことが根本原因です。OSはパスを正直に解釈するため、../ の連鎖を素直に処理してしまいます。
ディレクトリトラバーサル攻撃の仕組み
具体的にどのような形で攻撃が行われるのかを見てみましょう。
典型的な攻撃パターン
たとえば、Webアプリケーションに次のようなURLが存在するとします。
https://example.com/files?name=report.pdf
このとき、アプリケーション内部では name パラメータの値をそのままファイルパスに使って、ファイルを読み込む処理をしている可能性があります。
攻撃者はここに ../ を挿入します。
https://example.com/files?name=../../../../etc/passwd
サニタイズ(入力値の無害化)が不十分であれば、アプリケーションはこのパスをそのまま処理してしまい、Linuxのパスワードファイル /etc/passwd の内容を返してしまいます。../../../../ と4回繰り返しているのは、ドキュメントルートの階層の深さを推測してルートディレクトリまで上がるためです。実際の攻撃では、階層数を変えながら複数回試みられます。
エンコードによる検出回避
単純な ../ をフィルタリングしているだけでは不十分です。攻撃者はURLエンコードを使って検出をすり抜けようとします。
../ → %2e%2e%2f(URLエンコード)
../ → %252e%252e%252f(二重エンコード)
../ → ..\(Windowsのバックスラッシュ)
../ → ..%c0%af(不正なUTF-8エンコード)
二重エンコードが特に厄介です。Webサーバーが一度URLデコードした後、アプリケーションがさらにデコードするという二段階の処理がある場合、最初のデコードでは %252e が %2e に変換されるだけで無害に見えます。アプリケーションレイヤーで二度目のデコードが行われて初めて . になるため、フィルタリングをすり抜けられます。
IPAの「安全なウェブサイトの作り方」でも、こうした多様なエンコードパターンを考慮した対策が推奨されており、文字列マッチングだけに頼ることの危険性が明示されています。
ディレクトリトラバーサル攻撃による被害
攻撃が成功すると、どのような被害が起きるのでしょうか。影響は「読み取り」だけにとどまらない場合があります。
個人情報・機密情報の漏洩
最も頻繁に起きる被害です。サーバーの設定ファイル(/etc/passwd、/etc/shadowなど)や、アプリケーションの設定ファイル(データベースの接続情報、APIキーなど)が読み取られると、情報漏洩として重大なインシデントになります。
ユーザーの個人情報を格納したファイルが公開ディレクトリ外に置かれていても、ディレクトリトラバーサルの脆弱性があれば意味がありません。「非公開場所に置いているから安心」という考え方は、この攻撃の前では通用しないのです。特に .env ファイルや config.php などの設定ファイルには、クラウドサービスのアクセスキーやデータベースの認証情報が記載されていることが多く、これが漏洩すると二次被害・三次被害へと連鎖します。
アカウントの乗っ取り・なりすまし
パスワードファイルやセッション情報が格納されたファイルを取得されると、アカウントへの不正アクセスに使われる可能性があります。特に、Webアプリケーションが生成する一時ファイルやセッションファイルのパスが予測可能な場合、深刻なリスクになります。
PHPアプリケーションではセッションファイルが /tmp/sess_[セッションID] という形で保存されることがあります。セッションIDを別の手段で入手した攻撃者がこのファイルを読み取ることで、正規ユーザーのセッションを乗っ取れてしまいます。
データの改ざん・削除
書き込み可能な脆弱性が存在する場合、単なる情報漏洩にとどまらず、設定ファイルの書き換えや重要データの削除も起こり得ます。悪意のあるコードをサーバー上に設置するための足がかりにもなります。Webシェルと呼ばれる遠隔操作ツールを設置されると、攻撃者はサーバーをほぼ自由に操作できる状態になります。
実際の被害事例
抽象的な説明だけでなく、実際に起きたインシデントを見ることで、脅威の現実感をつかめます。
大手電機メーカーの機密情報流出
国内の大手電機メーカーがサイバー攻撃を受け、取引先情報や技術仕様などの機密データが外部に流出した事例では、ディレクトリトラバーサルを含む複数の手法が組み合わせて使われたと報告されています。一度侵入口ができると、攻撃者は時間をかけて内部を探索するため、被害が発覚するまでに数ヶ月かかることもあります。初期の侵入口が小さな脆弱性であっても、横断的に内部ネットワークへ侵入する「ラテラルムーブメント」の起点になり得る点が、この種の攻撃の恐ろしさです。
コンピュータソフトウェア著作権協会の個人情報漏洩
コンピュータソフトウェア著作権協会(ACCS)の事例では、Webアプリケーションの脆弱性を突いた攻撃により、個人情報が不正に取得されました。この事例はセキュリティ研究者による脆弱性の公開報告という形を取りましたが、Webアプリのパス処理における不備がいかに実被害につながるかを示す事例として広く知られています。発覚後の対応コストや信頼失墜も含めると、一度の情報漏洩が組織に与えるダメージは計り知れません。
著名プロダクトにも潜む脆弱性
セキュリティ製品そのものにディレクトリトラバーサルの脆弱性が発見されたケースも存在します。2022年に公開されたCVE-2022-48362(ManageEngine Desktop Centralの脆弱性)や、2023年のCVE-2023-2825(GitLabのパストラバーサル脆弱性)など、著名なプロダクトも例外ではありません。「信頼性の高いベンダーの製品だから安全」という過信は禁物です。自社で開発したコードだけでなく、導入しているOSSやフレームワークのCVE情報を定期的に追うことも重要なセキュリティ対策のひとつです。
ディレクトリトラバーサル攻撃への対策
対策は複数の層で考えることが重要です。「一つ入れれば安心」ではなく、根本対策・設定対策・監視対策を組み合わせることが現実的なセキュリティを実現します。
根本的な対策①:外部入力でファイルパスを直接指定しない
最も確実な対策は、外部からのパラメータをファイルパスの構築に直接使わない設計にすることです。
たとえば、ファイルをダウンロードさせる機能であれば、URLパラメータにファイル名を直接渡すのではなく、ファイルIDと実際のファイル名のマッピングをサーバー側で管理する方式が推奨されます。
# 危険な設計
https://example.com/download?file=report.pdf
# 安全な設計
https://example.com/download?id=1234
(サーバー側で id=1234 → report.pdf を解決)
この方式であれば、攻撃者がURLパラメータにどのような値を入れても、対応するマッピングが存在しない限りファイルアクセスは行われません。設計段階でこの原則を取り入れることが、最もコストの低い対策です。後から修正しようとすると、コードの大規模な改修が必要になる場合があります。
根本的な対策②:ベースディレクトリを固定し、パスを検証する
どうしても外部入力をもとにファイルにアクセスする必要がある場合は、処理前にパスの正規化とベースディレクトリチェックを行います。
多くのプログラミング言語にはパスを正規化する標準関数が用意されています。Pythonであれば os.path.realpath()、Javaであれば Path.normalize()、PHPであれば realpath() などです。正規化後のパスが意図したベースディレクトリ以下に収まっているかを startsWith() などで確認することで、../ による上位ディレクトリへの遡りを防げます。
ただし、ここで注意が必要なのは「ファイル名に ../ が含まれているかどうかを文字列マッチングで確認する」方式は不完全だという点です。前述のURLエンコードやOSごとのパス区切り文字の違いによって、簡単に回避されてしまいます。文字列フィルタリングではなく、正規化後のパスを検証するというアプローチが本質的な対策です。
保険的な対策①:Webサーバーのアクセス権限を適切に設定する
サーバー上のファイルのアクセス権限(パーミッション)を最小権限の原則で管理することで、脆弱性が存在しても被害を最小化できます。
Webアプリケーションのプロセスが読み取れるのは、動作に必要なファイルのみに絞るべきです。/etc/shadow や秘密鍵ファイルに対して、Webサーバーのユーザー(www-data や apache など)が読み取り権限を持っているケースは意外と多く、これが被害を拡大させます。Linuxであれば chmod や chown で権限を見直し、Webサーバープロセスが不要なファイルにアクセスできない状態を維持することが重要です。
保険的な対策②:公開ディレクトリに機密ファイルを置かない
機密情報を含むファイル(設定ファイル、ログファイル、バックアップファイルなど)は、Webサーバーのドキュメントルートの外に配置するのが原則です。
ただし前述の通り、ディレクトリトラバーサルはドキュメントルートの外にも到達できるため、これだけでは不十分です。特にバックアップファイル(.bak、.old、.backup などの拡張子)がドキュメントルート内に残っているケースは危険です。自動バックアップツールが意図せずWebからアクセス可能な場所にファイルを作成していることもあるため、定期的な棚卸しが必要です。
WAFの導入
WAF(Web Application Firewall)は、ディレクトリトラバーサルを含む既知の攻撃パターンを検知・ブロックする仕組みです。アプリケーション側の修正が困難な場合の緊急対応としても有効ですが、WAFはあくまで補助的な対策と位置づけるべきです。
WAFが検知できるのは、シグネチャベースの既知パターンに限られます。新しいエンコード手法や、アプリケーション固有のロジックを悪用した攻撃は通り抜けることがあります。「WAFを入れたから安全」という認識は危険で、根本的なコードレベルの対策と並行して導入するものです。クラウドサービスであればAWS WAFやCloudflare WAFなど、導入コストを抑えながら活用できる選択肢も増えています。
脆弱性診断の定期実施
自社のWebアプリケーションにディレクトリトラバーサルの脆弱性が潜んでいるかどうかを確認するには、定期的な脆弱性診断が有効です。
特に次のタイミングでの診断が推奨されます。
新規Webサービスのリリース前
大規模な機能追加・改修後
外部からのセキュリティ指摘を受けた後
年次のセキュリティ監査として
自動スキャナーによる診断は低コストで継続的に行える一方、手動の診断はビジネスロジックを理解したうえで深く検査できるという利点があります。OWASPが公開しているテストガイドラインでも、パストラバーサルのテスト手順が体系的にまとめられており、診断の品質基準として参照できます。目的とリスクに応じて自動・手動を組み合わせることが現実的なアプローチです。
対策でよく見落とされる盲点
多くの解説記事では触れられていませんが、実務上で頻繁に問題になるポイントがあります。
Windowsサーバー固有のパス処理
Linuxを前提にした対策では、Windows環境での攻撃を見落とす可能性があります。Windowsのパス区切り文字はバックスラッシュ(\)であり、..\ という形でのトラバーサルが試みられます。また、NTFSの代替データストリームやUNCパス(\\server\share)を利用した回避手法も存在します。
開発環境がLinuxでも本番環境がWindowsのケース、あるいは混在環境では特に注意が必要です。パス正規化の処理がLinuxの / しか考慮していない実装だと、Windows環境では想定通りに動作しないことがあります。
アップロードファイルの保存先
ファイルアップロード機能を持つWebアプリケーションでは、アップロードされたファイルをどこに保存するかが重要です。ユーザーが指定したファイル名をそのまま保存パスに使うと、../../../etc/cron.d/malicious のようなパスでシステムファイルを上書きされる恐れがあります。
アップロード時にファイル名をサーバー側でUUIDなどのランダムなIDに置き換えて保存する方式が安全です。元のファイル名はデータベースで管理し、保存パスとは切り離すことが基本です。
ログファイルの参照機能
管理画面にログファイルを閲覧する機能がある場合、そのパラメータも攻撃の対象になります。「管理者しか使わない機能だから」という理由でセキュリティチェックが甘くなりがちですが、管理者の認証情報が漏洩した場合や、セッション固定化攻撃と組み合わせた場合に悪用されることがあります。内部向けツールや管理機能であっても、外部からの入力を扱う以上、同じ基準でセキュリティを確保することが必要です。
フレームワークやライブラリへの過信
「有名なフレームワークを使っているから安全」という認識も危険です。フレームワーク自体の脆弱性は別として、ファイルパスを直接操作するコードを開発者が自分で書く場面では、フレームワークは保護してくれません。ORMがSQLインジェクションを防いでくれるのと同様のイメージでパストラバーサルも自動的に防がれると思い込んでいるケースは多く、これが見落としにつながります。
まとめ
ディレクトリトラバーサルは、古くから知られた攻撃手法でありながら、依然として多くのWebアプリケーションで発見される脆弱性です。IPAへの脆弱性届出でも継続的に報告されており、「知っているつもりで対策が甘い」という状況が繰り返されています。
対策の本質は「外部からの入力を信頼しない」という原則に尽きます。ファイルパスを構築する際にユーザー入力を使わない設計にすることが最も確実であり、それが難しい場合はパスの正規化と検証を正しく実装することが求められます。
WAFや権限設定といった多層防御は重要ですが、根本的なコードレベルの対策なしには補助的な役割にとどまります。特に、文字列マッチングによるフィルタリングだけで対策した気になっているケースは、エンコードによる回避に対して無防備です。
セキュリティは「一度設定したら終わり」ではなく、定期的な診断と見直しを繰り返すことで維持されるものです。自社のWebサービスの脆弱性に不安がある場合や、診断の実施を検討している場合は、専門のセキュリティベンダーへ相談することをおすすめします。第三者の目線で診断を受けることで、内部だけでは気づきにくい盲点を発見できる可能性があります。