FortiGuard Labs 脅威リサーチ
URL(Uniform Resource Locator)、いわゆるWebアドレスは、スキーム、オーソリティ、パス、クエリ、フラグメントの5つのコンポーネントで構成されます。それぞれの要素については、http://host-authority/path/?query-param=1#fragmentの例でご確認いただけます。
Webアプリケーション環境では、常にURLパスを使用して、Webリクエストと指定されたWebサービスとがバックエンドでマッピングされます。一般的に、Webアプリケーションはセキュリティ対策として、パスフィルターのメカニズムを備えており、不正なユーザーがURLを介して目的外の機能を利用するのを防止します。
Java Webフレームワークは、インターネット上で最も広く導入されているWebサービスの一つです。我々の経験に基づいて言うと、パスフィルターはWebサーブレットでも広く利用され、目的外のサービスアクセスの防止に役立っています(サーブレットとはJavaプログラミング言語クラスであり、要求 / 応答プログラミングモデルでアクセスされるアプリケーションをホストするサーバーの機能を拡張するために使用されます)。こうした理由から、フォーティネットは利用者の多いJavaオープンソースプロジェクトでコード監査を実施することにしました。評価を実施する中で、2つのオープンソースプロジェクト、Apache ShiroとdotCMSで興味深いバイパスの脆弱性がいくつか見つかりました。脆弱性識別番号はCVE-2021-41303とCVE-2022-35740です。
次のセクションでは、フォーティネットが発見したパスフィルターバイパスの方法を解説します。
Apache Shiro™は強力かつ使いやすいJavaセキュリティフレームワークで、認証、許可、暗号化、セッション管理などを行います。
Apache Shiroは2とおりの方法、すなわちSSHまたはWeb(SpringやSpring BootなどのWebフレームワークに統合されている場合)で使用できます。このブログ記事では、Apache ShiroでSpring Bootを使用したときに認証がバイパスされる脆弱性を取り上げます。
次のデモでは、不正ユーザーのアクセスを防止するために、Apache Shiroで/admin/パスを保護するSpring Bootアプリケーションを作成しています。
我々が「/admin/」パスのエンドポイントにアクセスしようとすると、「/login」ページにリダイレクトされます。フォーティネットは認証されていないため、これは通常の動作です。
しかしながら、Apache ShiroとSpring BootでURLパスの解析方法が異なることによる脆弱性が存在しています。この点を検証するため、フォーティネットは「/admin/aaa」への正常なリクエストがどのように解析されるかを精査しました。
図4のパスにアクセスしようとすると、Apache ShiroでpathMatchesメソッドが呼び出されます。図5と図6で、「/admin/*」のパターンと我々が入力した「/admin/aaa」とが比較され、trueが返されます。
adminルートは一致しましたが、この時点でフォーティネットは未認証のため、ログインページにリダイレクトされます。ここまでは、すべて正常な動作です。
それでは、不正な形式のバイパスリクエストである「/admin/%2e%2e」が送信されるとどうなるか見てみましょう。
pathMatches関数が呼び出されますが、今回は入力パスが「/admin/%2e%2e」ではなく「/」として処理されます。
これは、Apache ShiroがこのURLパスをデコードする際に「/admin/..」を変換し、その結果ルートディレクトリに戻るからです。これにより、認証チェックはバイパスされます。Apache ShiroはこのURLパスを、公開アクセス可能と見なされる「/」と同等に扱うからです。次に、Apache Shiroは処理を実行するため、リクエストをSpring Bootに転送します。
しかし、Spring Bootのパスマッピングでは、これと同じ入力パスが違う方法で処理されます。この例の場合、Spring Bootは入力パスを「/admin/」配下のエンドポイントであると認識し、図11のように、保護されたコンテンツを攻撃者に開示します。
Apache ShiroとSpring Bootの解析方法が違っていたために、我々はApache Shiroの認証メカニズムをバイパスすることができました。
タイムライン
dotCMSは、Javaを基盤とするオープンソースのハイブリッドCMS(コンテンツ管理システム)です。フォーティネットはdotCMSの評価を実施し、CORS攻撃、クロスサイトリクエストフォージェリ、およびクロスサイトスクリプティングの問題点を複数発見しました。ユーザーが管理者権限でアクセスした場合、これらは重大な脅威になり得ます。
ただし、dotCMSではデフォルト設定により、すべての管理エンドポイントでグローバルにXSS対策が有効になっているため、これらの問題は悪用できないこともわかりました。
このドキュメントでは、管理ディレクトリ(/html、/dotAdminなど)配下のすべてのファイルへの直接アクセスは、有効なRefererまたはOriginヘッダーを付けてリクエストを送信しない限り、dotCMSによってブロックされると説明されています。
これを検証するため、フォーティネットはXSSペイロードを使ってエンドポイントへのアクセスを試みました。
http://localhost:8080/c/portal/layout?_content_selectedStructure=%3Csvg/ onload=prompt(2)/%3E&_content_struts_action=%2Fext%2Fcontentlet%2Fedit_contentlet &p_p_action=1&p_p_id=content&p_p_state=maximized |
RefererまたはOriginヘッダーがないため、アプリケーションはユーザーを/dotAdmin/にリダイレクトします。
我々は、dotCMSでパスフィルターメカニズムがどのように機能するかを深く理解するために、このメカニズムをバイパスできるかどうか、コードを分析して調べることにしました。
dotCMSバージョン22.05のソースコードを調べてみると、com/dotcms/filters/interceptor/dotcms/XSSPreventionWebInterceptor.javaの28行目以降に、デフォルトで保護されるパスが定義されています。
保護されたパスと着信リクエストが一致すると、そのリクエストはインターセプトされ、com/dotcms/util/SecurityUtils.javaのsecurityUtils.validateReferer()に渡されます。
基本的に、このメソッドでは以下を確認します。
結果がtrueであれば、リクエストが処理されます。そうでない場合は、401 Unauthorizedのステータスが返されるか、例外ページにリダイレクトされます。
我々は、Origin / Refererヘッダーのバイパスを試みる代わりに、もっと簡単な方法を思いつきました。パスでバイパスを実行してみてはどうだろうか? そうすれば、そのパスと保護されたパスが一致しない場合、それ以上検証を続ける必要はありません。
これを踏まえたうえで、我々はマトリックスパラメータを使用したバイパスを発見しました。マトリックスパラメータはクエリパラメータに代わるものですが、より柔軟性が高く、パスの中のあらゆる場所に挿入できます。
たとえば、次のクエリパラメータがあるとします。
http://example/index1/index2.jsp?a=1&b=2
これを、同じ意味を持つ次のマトリックスパラメータに変換できます。
http://example/index1/index2.jsp;a=1;b=2
これが分かれば、目的のペイロードをマトリックスパラメータに変換し、ホワイトリストを効果的にバイパスすることができます。
http://localhost:8080/c;fg=pt/portal/layout?_content_selectedStructure=%3Esvg/ onload=prompt(2)/%3C&_content_struts_action=%2Fext%2Fcontentlet%2Fedit_contentlet &p_p_action=1&p_p_id=content&p_p_state=maximized |
図16のように、このリクエストは首尾よくXSS対策をバイパスし、不正なXSSペイロードが出力に表示されています。
タイムライン
結論として、パスフィルターメカニズムは容易に悪用され、包括的なフィルターメカニズムを実装するには多大な労力を要します。ここで紹介した2例以外にも、パスフィルターが苦もなく回避される事例を他のリサーチャーからいくつも提示されました。
しかしながら、もう一つの重要な教訓として、他のフレームワークに統合される製品や依存する製品を開発する場合、開発者はそのフレームワークの特性を十分に理解しておく必要があるということも学びました。この教訓を生かし、Apache Shiroの例で示したような脆弱性がうっかり持ち込まれるのを防ぐことができます。
FortiGuard Labsは、前述したすべての脆弱性に対応する以下のIPSシグネチャをリリースしました。
Apache.Shiro.Authentication.Bypass
dotCMS.Core.XSSFilter.Bypass
ユーザーの皆様には、ベンダーが提供する以下の最新パッチの適用を強くお勧めします。
Apache Shiro: https://shiro.apache.org/download.html
dotCMS: https://github.com/dotCMS/patches-hotfixes/tree/master/com.dotcms.security.matrixparams
注:お使いのソフトウェアやアプリケーションで上記のような評価をご希望の場合は、FortiGuard Labsが、カスタマイズされた脆弱性評価および侵入テストサービスを提供いたします。製品のセキュリティ向上に是非お役立てください。詳細についてはこちらをご覧ください。