セキュリティブログ

NGINX LDAP AUTHに関する脆弱性

NGINX LDAP AUTHに関する脆弱性

更新日:2023.11.21

こんにちは、くまさかです。


日本時間の2022/04/10 早朝頃から、NGINXとLDAPというキーワードに注目が集まっています。それらの組み合わせによる設定不備や脆弱な構成について、NGINXからアドバイザリが公開されていますが、弊社での検証結果も踏まえ、解説記事としてまとめました。

対象

まず、NGINX のブログでも解説がありますが、本脆弱性は、標準のNGINX自体に内包されている機能に問題があるわけではありません。 ldap認証モジュールの選択肢の一つである、nginxinc上に存在するnginx-ldap-authを利用している場合に影響を受けます。 もちろん、LDAP認証を利用していない場合は、影響を受けません。
nginx-ldap-authを利用していると考えられる特徴は以下の通りです。

  • LDAP認証を使っている
  • NGINXの設定ファイルに、auth_request という項目が存在する
  • NGINXの設定ファイルに、proxy_set_header X-Ldap-URL という項目が存在する
    • 引数実行の場合は、必ずしも存在しない
  • nginx-ldap-auth-daemon.py というプロセスや、実行しているコンテナが、auth_request のリダイレクト先に存在する
    • 自社製の認証デーモン等がnginx-ldap-auth から派生させたものである場合、同様の影響を受ける可能性が考えられます。その際は、ファイル名等が異なる可能性も視野にいれてください

nginx-ldap-authは、執筆時点バージョン管理が確認できておらず、根本的な修正済みも未リリースの為、利用する特徴に一致すれば、 対応を検討することを推奨します。

影響

対象の場合、ldap injection により、ldapサーバへ任意のクエリを送付される可能性があります。 これにより、ldap認証を用いるコンテンツに対し、意図されないユーザーによるアクセスが可能となり、不正に情報を取得される可能性があります。

対策

執筆時点では、nginx-ldap-auth上での修正はありません。


そのため、ワークアラウンドとして、以下が挙げられます。

  1. ldapを無効化する
  2. nginx-ldap-auth 以外をldap認証モジュールとして利用する
  3. NGINXが本件に関するアドバイザリとして紹介している、不要なパラメータや設定していない項目へ空の値("")を明示設定する
    NGINX の ブログ

本記事では、NGINXのアドバイザリの内容にもう少し触れていきます。

1. nginx-ldap-auth に、ldapの接続情報を 引数 で与えている場合

https://www.nginx.com/blog/addressing-security-weaknesses-nginx-ldap-reference-implementation/#condition-1 に関するお話です。

nginx-ldap-authでは、引数パラメータよりも、リクエストヘッダからくる設定が優先されます。 そのため、細工されたヘッダを受け取った場合、ldapのバックエンド用のパラメータが書き換えられる可能性があります。


対策としては、NGINXの設定ファイル上の認証先設定の領域に、引数で指定しているパラメータを空で上書きする設定が挙げられています。

これにより、細工されたヘッダがnginx-ldap-authに到達する前に、空に書き換えられ安全なリクエストがnginx-ldap-authに到達します。

location = /auth-proxy {
    ...
    proxy_set_header X-Ldap-URL      "";
    proxy_set_header X-Ldap-BaseDN   "";
    proxy_set_header X-Ldap-BindDN   "";
    proxy_set_header X-Ldap-BindPass "";
    ...
}

2. nginx-ldap-auth に、ldapの接続情報を nginxの設定等から X-Ldap-* で渡している場合

https://www.nginx.com/blog/addressing-security-weaknesses-nginx-ldap-reference-implementation/#condition-2 に関するお話です。

nginx-ldap-auth では、nginx設定ファイル上で、nginx-ldap-authリクエスト時の追加ヘッダとして、X-Ldap-*指定することでldapの接続情報を設定できます。 最低限の設定としては、以下の値を指定することで利用できます。

X-Ldap-URL
X-Ldap-BaseDN
X-Ldap-BindDN
X-Ldap-BindPass

しかし、上記設定のみを行うと、オプションなldapの接続情報を、細工されたヘッダから受け取った場合、書き換えられる可能性があります。


対策としては、オプションなldapの接続情報を空で上書きする設定が挙げられています。 これにより、細工されたヘッダをNGINX上で受け取ったとしても、本設定により空に書き換えられ、安全となったリクエストがnginx-ldap-authに到達します。

location = /auth-proxy {
    ...
    proxy_set_header X-Ldap-Template "";
    proxy_set_header X-CookieName    "";
    proxy_set_header X-Ldap-Realm    "";
    proxy_set_header X-Ldap-Starttls "";
    ...
}

https://www.nginx.com/blog/addressing-security-weaknesses-nginx-ldap-reference-implementation/#condition-3 では、ldapのパラメータとして活用できる(), = をバックエンドサーバ等で除外する事を伝えています。

バックエンドに手を加えられる状況であれば、最も有効でしょうが、難しい場合は、上記1. 2. の通り、NGINXの設定ファイルでのワークアラウンドが現実解となってきます。

なお、将来的には、バックエンドでそのような対策をとるとNGINXアドバイザリ内では明記しているので、将来的には、nginx-ldap-auth にもそのようなアップデートが入る可能性も考えられます。

シグネチャで検出するには?

本脆弱性は、フロントのNGINXへldapの接続情報となる細工したリクエストを送付することで、攻撃の足がかりとします。

そのため、NGINXの設定ファイルへの変更が難しい場合、フロントに対するリクエストヘッダに、以下のようなヘッダが含まれないかをIPS等で確認することが有効です。

X-Ldap-URL
X-Ldap-BaseDN
X-Ldap-BindDN
X-Ldap-BindPass
X-Ldap-Template
X-CookieName
X-Ldap-Realm
X-Ldap-Starttls
....

最新の全ての項目は、nginx-ldap-auth のリポジトリをご確認ください。

本脆弱性の発動イメージ解説

NGINXでは、認証サービスを上げているHTTPDへリダイレクトすることで認証を利用する設定方法 auth_requestがあります。

本設定を用いることで、NGINXがユーザから受け取ったクレデンシャル入りのクエリを、NGINX内部でauth_request先へリダイレクトします。 auth_request先のHTTPDでは、認証結果のレスポンスを返し、NGINXが受け取るような動きをします。その結果や、NGINX上の設定を元にコンテンツの表示を行っています。


今回の脆弱性では、内部リダイレクト後にauth_request先へ渡されるヘッダがクエリによって挿入可能であり、auth_request先である、nginx-ldap-authでは、検証を行っていなかったため、これらの組み合わせによって問題となりました。


正常なユーザからのクエリが来た場合には、以下の情報がnginx-ldap-auth へリダイレクトで渡されます。

  1. NGINXが外から受け取ったリクエストに含まれるユーザクレデンシャル
  2. NGINXの設定ファイル記載の、ldap接続情報が書かれたHTTPヘッダ

上記の内容を合わせたユーザクレデンシャル + ldap接続情報が、nginx-ldap-authへ渡されることで、ldapサーバへの接続や検索を行い、認証結果の返却を行います。
(1.のリクエストに対して、2.を加筆するようなイメージを持ってもらえればと思います。)


以下は正常なクエリ時のldapログのサンプルです。

正常なクエリのldapログ

本クエリでは、bobというユーザで認証をかけています。 ログからも、検索フィルタがcn=bobの、(cn=%(username)s)フォーマットで実施されていることが確認できます。


さて、この認証クエリですが、2.で加筆しないヘッダ項目を 1. の時点で明示指定するとどうなるでしょうか。 この場合、2. では一切の加筆が行われず、nginx-ldap-auth へ 1.の時点の値が送付されてしまいます。 今回の脆弱性では、この動きを活用し、 1. のリクエストに、細工したヘッダを付与することで、ldap接続情報へ変更を加え攻撃を実現します。

例えば、先ほどのldapログのサンプルを取得した環境へ、細工したクエリを送付することで、以下のようにフィルタを改変することが可能です。

フィルタを改変したクエリのldapログ

&(cn=... と、filter項目が改変され任意の検索を実行しています。


このようなユーザクエリによるinjectionを防ぐには、1. のリクエストでどのような値が設定されたとしても、2. で上書きする対策が有効です。 具体的には、先ほど、対策でも紹介した通り、X-Ldap-* へ空のパラメータを上書きする形が、NGINXアドバイザリにて紹介されました。


簡単ではありますが、話題になり始めたnginx-ldap-authに関して、解説させていただきました。

GMOサイバーセキュリティ byイエラエ株式会社 では、本年度にSOCイノベーション事業部を発足しており、脆弱性情報の収集や発信により一層力を入れていきます。 今後もこのような解説情報の継続的な提供を目指していきますので、引き続き弊社活動をよろしくお願いいたします。


2022年04月12日 08:07 PM (JST): 公開

2022年04月14日 08:54 AM (JST): スタイルを一部修正

2023年11月21日 09:00 PM (JST): 記事更新日時のシステムアップデート

セキュリティ診断のことなら
お気軽にご相談ください
セキュリティ診断で発見された脆弱性と、具体的な内容・再現方法・リスク・対策方法を報告したレポートのサンプルをご覧いただけます。

関連記事

経験豊富なエンジニアが
セキュリティの不安を解消します

Webサービスやアプリにおけるセキュリティ上の問題点を解消し、
収益の最大化を実現する相談役としてぜひお気軽にご連絡ください。

疑問点やお見積もり依頼はこちらから

お見積もり・お問い合わせ

セキュリティ診断サービスについてのご紹介

資料ダウンロード
RECRUIT

私たちと一緒に、
脆弱性のない世界を創っていきませんか