アプリケーション外でも発生する脆弱性 パストラバーサル
パストラバーサル(Path Traversal、以下パストラバーサルで統一) は、本来アクセスできないディレクトリに存在するファイルに対して、脆弱性を悪用してアクセスする攻撃手法・脆弱性です。
この脆弱性はディレクトリトラバーサル(Directory Traversal)とも呼称されています。
本記事では、パストラバーサルの脆弱性についてを説明した後、対策方法と、発展的な「nginx で発生してしまうパストラバーサル」についても触れていきます。
パストラバーサルとは?
説明のため、1 つのアプリケーション例を題材として話を進めていきます。
以下のような構成の Web サーバがあったとしましょう。
ユーザーはインターネットを通じて、公開ディレクトリとして指定されている public ディレクトリへアクセスが行えるものとします。
また secret のディレクトリに対しては、ユーザがアクセスできないように制御を行っています。
仮にパストラバーサルの脆弱性が存在した場合、本来アクセスできない領域である secret のディレクトリに対して、脆弱性を悪用することでアクセスできる場合があります。
secret ディレクトリに機密データが存在した場合には、パストラバーサルが原因で漏洩事故などにつながります。
パストラバーサルの影響
Web サーバにパストラバーサルの脆弱性が存在すると、どのような被害が考えられるでしょうか?
影響としては、以下が考えられます。
個人情報や企業データといった機微情報の漏洩・流出
ファイルの読み込み箇所などでパストラバーサルが発生した場合、「アプリケーションサーバー内」に存在するファイルを読み込まれる可能性があります。
これらのファイルの中に個人情報を含むデータが存在した場合、大きな問題となります。
通常のアプリケーションであれば、データベースなどに個人情報はまとまっていますが、中にはエラーログやアクセスログなどに個人情報が入ってくるケースがあります。
そのため「このサーバでは機微な情報を扱ってない」と言った考え方で対策を怠るのは、非常に危険です。
サーバ上のデータの書き換え
パストラバーサルは、ファイルの読み込みだけで発生する問題ではありません。
この問題は、書き込み箇所でも発生することがあります。
書き込みで問題が発生した場合、データを不正に書き換えることによる完全性の侵害が考えられます。
また発展的な内容としては、スクリプトなどを書き換えることによる不正なコード実行などが挙げられます。
たとえばサーバ上にアップロードされた PHP などのスクリプトを書き換え、本来と違う挙動にした上で実行させ、更なる攻撃につなげる可能性があります。
クレデンシャル情報の漏洩による横展開
何かしらの認証情報となるクレデンシャルがパストラバーサルによって漏洩した場合、更なる改ざんや漏洩といった問題につながることがあります。
たとえば AWS や GCP といったプラットフォームのクレデンシャル情報が漏洩すると、そこを足がかりに更なる侵害・被害を受けてしまいます。
開発中であれば「そんなファイルはサーバーに上げていない」と思われるかもしれません。
しかし、本当にサーバーにアップロードしていないでしょうか?
開発者にとって、 .ssh .git といった隠しディレクトリや隠しファイルは盲点かもしれません。
ディレクトリトラバーサルのメカニズム
パストラバーサルにおける影響を知ることで、この脆弱性の危険度を認識していただけたと思います。
ここからは、この脆弱性の発生メカニズムについて見ていきます。
通常、ディレクトリトラバーサルの発生原因は非常にシンプルです。
この問題の多くは、プログラムによって何かしらのファイルを読み込んだり、書き込む際のロジックに不備があることで発生します。
外部パラメータ、つまりユーザからの入力によって「読み込み・書き込みを行うファイル」を決定する処理があった場合、パラメータに「パス文字」などが入り込むことで、この脆弱性は発現します。
たとえば、以下のようにファイルを開く処理があったとします。
このコードでは、 ユーザのリクエスト内容によって ./public/ ディレクトリにあるファイルを読み込む処理が記述されています。
しかし、 fileName に対して ../secrets/secret.key といった相対パス文字( ../ )を含んだリクエストを送った場合、パスは ./public/../secrets/secret.key となります。
すると、対象の ./public/ ディレクトリより上層の親ディレクトリ移動した後、 secrets ディレクトリへのアクセスとなります。
このように、パス文字などによってパストラバーサルの問題は発生します。
Windows におけるパストラバーサル
先ほどのパス文字 ../ は、Linux, OS X におけるパストラバーサルの説明でした。
Windows サーバの場合は、先述した UNIX 系の OS ではないため、パス指定の仕方が変わってきます。
たとえば、Windows の場合は ..\WINDOWS\win.ini といった形式のパス記述方式となるため、攻撃パラメータとなる相対パスの文字もそれに合わせて ..\ などに変わってきます。
これらのアクセスがあった場合、殆どのケースが攻撃であるため、WAF などを使い、アプリをセキュアにしていくことが大切です。
また、後述する対策方法を行い、根本的な問題解決をすることが重要です。
ディレクトリトラバーサルの対策方法
ディレクトリトラバーサルの対策は、一般的に以下の方法が実施されます。
- .. といった相対パスや、ショートカットの特殊ファイル名などを削除し、対象ファイルへのパスを計算する
- ファイル操作の際は、計算後のパスが、想定していたパス・ディレクトリ内であるかを検査する
先ほどの脆弱なコードでは、これらの対応がなされていませんでした。
つまり「ユーザから受け取ったパラメータをそのままパス計算に使い」、「計算結果が意図したパスとなっているかチェックしていない」ということです。
そのため、パストラバーサルの脆弱性が発生するコードとなっていました。
nginx で発生するパストラバーサル(エイリアストラバーサル)
ここまで基本的にはアプリケーションにおけるパストラバーサルについて解説を進めてきました。
暗黙的に「パストラバーサルはアプリケーションが原因でしか発生しない脆弱性」といったイメージを持たれているかたも居ると思います。
しかし、「nginx」という Web サーバのミドルウェアでも「nginx の設定ファイルの書き方を誤る」という条件下でこの脆弱性は発生します。
※この問題はパストラバーサルではなく、Alias Traversal・エイリアス・トラバーサルと呼ばれたりもします。
次の nginx の設定では、 example.com/static という URL のリクエストを受け取った場合、 alias によって指定されたパス /var/www/app/static/ 上のファイル参照が発生します。
このように、「ロケーションのパスの割り当て」を行うのが nginx の alias というディレクティブです。
ただ上記の設定を行なっている場合、次のリクエストを送ることで、パストラバーサルが発生します。
この URL をリクエストした場合、ドメインの後の /static ファイルパスが nginx の設定ファイルにマッチすることで alias ディレクティブが適用されます。
これにより、ファイル参照の起点が /var/www/app/static になります。
しかし、後続文字である ..%2f という ../ を URL エンコードした文字をそのまま処理してしまうため、1 つ親のディレクトリである /var/www/app/ へのファイル参照が発生します。
これにより /var/www/app/secrets/secret.key という、開発者の意図しないディレクトリへの参照が発生します。
これが、nginx におけるパストラバーサルの脆弱性です。
この問題は、1 行目の location のパラメータを修正することで修復できます。
問題となっているのは location で URL パスを選別する際の末尾の / です。
ここが無いと、攻撃者は nginx の仕様を悪用することで、制御文字となる ../ を nginx に解釈させることができます。
(nginx の設定による脆弱性を防ぐツールとして、 gixy という nginx の設定ファイル用静的コード解析ツールがあります)
このようにパストラバーサルの脆弱性は、アプリケーション固有の脆弱性ではないことがわかります。
さいごに
本記事では、パストラバーサルの脆弱性から、発展的な内容としてミドルウェア「nginx」で発生するパストラバーサルについて扱いました。
以下の記事では、node-tarにおけるパストラバーサルの脆弱性について実際のコードを確認しながらパストラバーサルの脅威について解説していますので、より詳しく知りたい方におすすめです。
npmにも影響があるnode-tarのパストラバーサルの脆弱性 CVE-2021-32804
「脆弱性を防ぐ」という行為はとても難しく、知識だけではなく、多くの努力が必要です。
本記事を通して「アプリケーションだけ直しておけば安全」と言った誤った考え方は、非常に危険であることを理解いただけたと思います。
脆弱性とは、意図しない書き方や問題が起こりえない部分でも発生します。
そのため、脆弱性情報を収集したり、問題となる箇所を理解していくということが非常に重要です。
安全なアプリケーションを作っていくためには、さまざまなアプローチで多層的に守っていきましょう。
yamory では、脆弱性診断ではカバーできない継続的な開発をサポートするためにセキュリティ向上のためのモニタリングを支援しております。
是非一度お試しいただけると幸いです。