21年前の2019年XNUMX月XNUMX日
これは重大な脆弱性です。なぜなら...リクエストにはセッション Cookie も含まれます。数時間後、ゼロバイトをフィルタリングする一時的な修正が行われました (後で判明しましたが、これでは十分ではありませんでした。CRLF / ASCII 13、10 を挿入する可能性がまだあったため、ヘッダーやヘッダーを操作できるようになります) HTTP 応答のデータ、これはそれほど重要ではありませんが、それでも不快です)。同時に、問題はセキュリティ アナリストと開発者に転送され、バグの原因を見つけて排除しました。
Mail.ru メールは非常に複雑なアプリケーションです。応答の生成には、オープン ソース (フリー ソフトウェア開発者の皆様に感謝します) と社内開発の両方の、多数の異なるフロントエンド/バックエンド コンポーネントが関与する可能性があります。 nginx と openresty を除くすべてのコンポーネントを除外し、呼び出す前に問題を特定することができました。
OpenResty は、nginx 内で Lua スクリプトを記述できるようにする非常に人気のあるプラグインであり、いくつかの Mail.ru プロジェクトで使用されているため、問題は解決されたとはみなされていませんでした。そしてしばらくして、彼らは本当の理由と考えられる結果を理解し、開発者に推奨事項を作成するために、最終的にこの問題に戻りました。ソースコードの発掘に参加しました
- nginx では、ユーザー データの書き換えを使用する場合、一部の構成でディレクトリ トラバーサル (およびおそらく SSRF) が発生する可能性がありますが、これは既知の事実であり、静的構成アナライザーによって検出される必要があります。
Nginx 増幅 иジクシー Yandex から (はい、私たちもそれを使用しています、ありがとう)。 OpenResty を使用している場合、この機能は見落とされがちですが、これは構成には影響しませんでした。構成例:
location ~ /rewrite { rewrite ^.*$ $arg_x; } location / { root html; index index.html index.htm; }
結果
curl localhost:8337/rewrite?x=/../../../../../../../etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
... - Nginx には、書き換え行に null バイトが含まれている場合にメモリ リークを引き起こすバグがあります。リダイレクトが発行されると、nginx は行の全長に対応する新しいメモリ バッファを割り当てますが、ゼロ バイトが行終端文字である line 関数を通じて行をそこにコピーします。そのため、行はゼロまでしかコピーされません。バイト; バッファの残りの部分には初期化されていないデータが含まれます。詳細な分析が見られます
ここで .設定例(^@ゼロバイト)
location ~ /memleak { rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf"; } location / { root html; index index.html index.htm; }
結果
curl localhost:8337/secret -vv
...
curl localhost:8337/memleak -vv
...
Location: http://localhost:8337/secret
...
- Nginx は、サービス文字の挿入から GET パラメーターを保護し、書き換えで GET パラメーターのみを使用できるようにします。したがって、nginx のユーザー制御パラメータを介してインジェクションを悪用することはできません。 POSTパラメータは保護されていません。 OpenResty では GET パラメーターと POST パラメーターの両方を操作できるため、OpenResty 経由で POST パラメーターを使用するときに特殊文字を挿入することが可能になります。
構成例:
location ~ /memleak { rewrite_by_lua_block { ngx.req.read_body(); local args, err = ngx.req.get_post_args(); ngx.req.set_uri( args["url"], true ); } } location / { root html; index index.html index.htm; }
結果:
curl localhost:8337 -d "url=secret" -vv
...
curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
...
Location: http://localhost:8337/{...может содержать secret...}
...
さらなる反応
この問題は nginx と OpenResty の開発者に報告されましたが、開発者はこの問題を nginx のセキュリティ バグとは考えていません。 nginx 自体では、特殊文字を挿入してエラーを悪用する方法はありません。修正してください
ポートウィガー
では、何が間違いだったのでしょうか?また、それを防ぐために何ができるでしょうか?
nginxにバグがあったのでしょうか? はい、そうでした。メモリ内容のリークはいずれにしてもエラーだからです。
OpenRestyにバグがあったのでしょうか? はい、少なくとも OpenResty が提供する機能のセキュリティの問題は調査も文書化もされていません。
OpenRestyの設定や使用に誤りはありませんか? はい、明示的な記述がないため、使用されている機能のセキュリティについて未検証の仮定がなされたためです。
次のバグのうち、10000 ドルの報奨金が課せられるセキュリティ脆弱性はどれですか? 私たちにとって、これは通常は重要ではありません。どのようなソフトウェアでも、特に複数のコンポーネントが交差する部分、特に異なるプロジェクトや開発者によって提供されるコンポーネントでは、その作業のすべての機能が既知で文書化されており、エラーがないことを保証できる人は誰もいません。したがって、セキュリティ上の脆弱性は、まさにセキュリティに影響を与える場所で発生します。
いずれの場合も、明示的な指示があり、その必要がないことが明確に理解されている場合を除き、外部モジュール/API に入力される入力データを可能な限り正規化または制限/フィルター処理することをお勧めします。
正誤表
経験から
バグ報奨金 — 虫探しコンテスト
バグレポート - エラー通知
リダイレクト - リダイレクト
オープンソース - オープンソース
正誤表 - 間違いに取り組む
出所: habr.com