nginx
Security
HTTP_Splitting
CWE-113

nginxの設定ミスで起こるHTTP Splitting

はじめに

この記事は下記リンクの日本語翻訳記事です

https://github.com/yandex/gixy/blob/master/docs/en/plugins/httpsplitting.md

翻訳が誤っている場合はコメントか@no1zy_secまでお知らせいただけると幸いです。

[http_splitting] HTTP Splitting

HTTP Splitting は 不適切なバリデーションを使用する攻撃です。通常、Nginx (HTTP Request Splitting) やそのユーザー (HTTP Response Splitting) の背後にあるwebアプリケーションを対象としています。

攻撃者がNginxによって作成されたリクエストやレスポンスの中にnewline character(\n\r)を挿入できるときに脆弱性になります。

 どうやって見つけるか

  • リクエストの作成を担当する変数がディレクティブ内で使用されています。例: rewrite, add_header, proxy_set_header または proxy_pass
  • $uri$document_uri 変数がディレクティブ内で使用されています。なぜならURLエンコードされた値をデコードした値が含まれているからです。
  • 排他的な範囲から選択される変数。例: (?P<myvar>[^.]+)

排他的な範囲から選択された変数を含んだ設定の例:

server {
    listen 80 default;

    location ~ /v1/((?<action>[^.]*)\.json)?$ {
        add_header X-Action $action;
        return 200 "OK";
    }
}

Exploitation:

GET /v1/see%20below%0d%0ax-crlf-header:injected.json HTTP/1.0
Host: localhost

HTTP/1.1 200 OK
Server: nginx/1.11.10
Date: Mon, 13 Mar 2017 21:21:29 GMT
Content-Type: application/octet-stream
Content-Length: 2
Connection: close
X-Action: see below
x-crlf-header:injected

OK

見ての通り、攻撃者が x-crlf-header: injected をレスポンスヘッダーに追加することができます。
これが可能な理由:

  • add_header をエンコードまたは入力値をバリデーションしていない。
  • locationを処理する前にpathの値を正規化している。
  • 排他的な範囲の正規表現 [^.]* から $action の値が指定されている。
  • その結果、$action の値は see below\r\nx-crlf-header:injected と等価になり、レスポンスヘッダーが追加された。

対策

  • 安全な変数を試す。例: $uri の代わりに $request_uri
  • /some/(?<action>[^/]+ の代わりに /some/(?<action>[^/\s]+) を使用することによる排他的な範囲でのnew lineシンボルの使用を禁止する。
  • $uri を検証すると良いと思います。(変数に何が入っているのかわかっている場合のみ)

関連リンク

nginxの設定ミスで起こるSSRF
nginxの設定ミスで起こるパス トラバーサル
nginxの設定ミスで起こるMultiline response headers
nginxの設定ミスで起こるレスポンスヘッダの出力不備
nginxの設定ミスで起こるreferer/origin検証の問題
nginxの設定ミスで起こるHostヘッダフォージェリ
nginxの設定ミスで起こるリファラの検証不備