Nginx のエイリアストラバーサルの記事を読んで、実際に挙動を確認してみた

先日、[GIGAZINE](https://gigazine.net/) で **Nginx** の**エイリアストラバーサル**についての記事を見かけたので、実際に Nginx サーバを立ててみて挙動を確認してみました。

・GIGAZINE の記事
[スラッシュの有無だけでセキュリティにとんでもない大穴が空いてしまうNginxのありがちな設定ミスについて実例を踏まえて専門家が解説 - GIGAZINE](https://gigazine.net/news/20230708-nginx-alias-traversal/)

こちらの GIGAZINE の記事なんですが、セキュリティアナリストの ダニエル・マツモトさんという方のブログを、日本語で分かりやすく解説したような内容になっています。

・Hunting for Nginx Alias Traversals in the wild
https://labs.hakaioffsec.com/nginx-alias-traversal/

ちなみに、筆者は Nginx については仕事で何度か使ったことはありますが、設定ファイルを書いたことはなく（他のメンバーが書いていた）、Nginx そのものにあまり馴染みが無いというレベル感です。

## 結論

結論からお伝えすると「**location と alias の両方とも末尾にスラッシュを付ける**」こと、となるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/400907af-4a70-c4ea-2f08-e92be9a903b2.png)

## 事前準備

今回は、Nginx のコンテナを立てて確認を行いました。バージョンは参考記事に合わせて **1.24.0** としています。
コンテナを立ち上げて `http://localhost:8080` にアクセスして **Welcome to nginx!** のページが表示されるところまで進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/c353cf37-bfce-cdfb-fc91-997373aeb058.png)

次に、コンテナの中に入って `/var/images` ディレクトリを作成し、その配下に（記事に合わせて）JPEG ファイルを配置しておきます。
今回は、フリーの画像ファイルを適当にインターネットから拾ってきて、`profile.jpg` という名称で配置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/00f7e4c5-794d-07df-bdd8-99084bd2742a.png)

最後に、設定ファイルを編集して、`/var/log/nginx/access_test.log` にアクセスログが出力されるように指定しておきます。
編集後は `service nginx reload` を忘れずに実行しておきます。

```config:/etc/nginx/conf.d/default.conf
  access_log /var/log/nginx/access_test.log main;
```

## 挙動の確認

それでは実際に挙動を確認してみます。

まず最初に、参考記事の方で「Vulnerable」として紹介されている**脆弱性有り**の設定内容を適用します。

```conf:/etc/nginx/conf.d/default.conf
location /img {
  alias /var/images/;
}
```

参考記事にも書かれてあるのですが、「location で指定した `/img` の末尾にスラッシュを**付けない**」かつ
「alias で指定した `/var/images/` の末尾にスラッシュを**付ける**」という２つの条件が揃った時に**重大な脆弱性**が発生してしまうようです。

今回の設定内容が適用されている場合、Nginxは `/img` で始まる URL を全て `/var/images/` へ転送してしまうため、`/img/profile.jpg` にアクセスすると、`/var/images//profile.jpg` に転送され、連続スラッシュは無視されて `/var/images/profile.jpg` のデータが返るとのことです。
この挙動を確認してみると `200 OK` で返ってきました。ファイルにアクセスできているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/4dd7cd45-283e-e6d8-9614-f53536585145.png)

筆者はパスに色付けすると理解しやすかったので、こちらに記載しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/054b0adf-bd53-6aa7-c6e8-276ac94d7794.png)


次に、`/imgprofile.jpg` にアクセスしてみます。この場合は `/var/images/profile.jpg` に転送されると書かれてあるので、この挙動を確認してみます。この場合も `200 OK` で返ってきました。ファイルにアクセスできているようです。２つの URL で同じファイルにアクセスできることになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/74337c9c-2c00-40a9-41d5-70205fc15265.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/c9dd729e-ddc2-8d65-4f2c-289820b679ec.png)


さらに、`/img..` という URL にアクセスすることで、`/var/images/..` というパスで指定されるデータにアクセス可能とのことです。`..` は皆さんも馴染みがあると思いますが「1つ上のディレクトリ」「親ディレクトリ」のことになります。
つまり、`/var/images/..` は `/var/` となり、本来公開されていないはずのディレクトリまで閲覧することができてしまいます。危険な状態と言えるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/a9beafcf-0a1a-af82-f01e-b2be6e23f8e7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/7543d707-afa5-6cc8-08b0-73430c1a6de7.png)


設定ファイルの alias 指定で末尾のスラッシュを**付けず**に `/var/images` とした場合の挙動についても確認してみます。

```conf:/etc/nginx/conf.d/default.conf
location /img {
  alias /var/images; // 末尾のスラッシュを付けない
}
```

この設定内容だと、URLの「/img..」にアクセスしても「/var/images..」という名前のディレクトリを探すだけなので親ディレクトリのデータにアクセスされることはないとのことなので、挙動を確認してみます。`404 Not Found` が返ってきました。アクセスできないようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/90fc3ff4-a6f1-586e-d925-515b27b3aa0f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/21f3fddb-f099-6fbc-065b-1c5f360d6ea7.png)

ただし、「/var/images_confidential」のようなディレクトリが存在している場合は「/img_confidential」というURLでアクセスできてしまうとのことなので、この挙動も確認してみます。
`/var/images_confidential` ディレクトリを作成し、配下に `test.txt` を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/77d40d9d-78e2-19a0-5389-0a933691a20f.png)

「/img_confidential」のURLでアクセスしてると、`200 OK` が返ってきました。アクセスできるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/ff1ee47d-1554-d8f8-a435-c67625ff4e8f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/4755a616-fc46-7557-cafe-6194e85a09bd.png)

これらを踏まえると、冒頭に書いた結論のように「**location と alias の両方とも末尾にスラッシュを付けるべき**」ということになるようです。

## さいごに
今、Nginx を使っている方やこれから使う予定のある方は、今一度、設定ファイルを見直してみても良いかも知れません。
ダニエル・マツモトさんが、今回の脆弱性を外部からブラックボックステストできる[ツールを公開](https://github.com/hakaioffsec/navgix)されているようなので、（筆者は使っていませんが）気になる方は確認されてみてください。