
Apache Tomcat セキュリティバイパス脆弱性 PoC

最近、ApacheはApache Tomcat 7、8、9の複数のバージョンにセキュリティ回避の脆弱性が存在するというセキュリティアドバイザリを公開しました。攻撃者はこの問題を利用して、特定のセキュリティ制限を回避し、不正な操作を実行する可能性があり、これがさらなる攻撃に寄与する可能性があります。
Apache Tomcatのサーブレットアノテーションで定義されたセキュリティ制約は、サーブレットがロードされた後でのみ一度適用されます。このように定義されたセキュリティ制約は、URLパターンおよびその配下の任意のURLに適用されるため、サーブレットのロード順序に依存する可能性が高く、これによりリソースが不正アクセスするユーザーにさらされる可能性があります。
CVE-2018-1305
Apache Tomcat < 9.0.5
Apache Tomcat < 8.5.28
Apache Tomcat < 8.0.50
Apache Tomcat < 7.0.85
中リスク
Java EE は ACL 権限チェックに類似した ServletSecurity アノテーションを提供しており、サーブレットを修飾して保護するために使用できます。2つのサーブレットがある場合、Servlet1 のアクセスパスは "/servlet1/" で ServletSecurity アノテーションが追加され、Servlet2 のアクセスパスは "/servlet1/servlet2/" で ServletSecurity アノテーションはありません。初めて servlet1/servlet2 にアクセスすると、servlet1 の ServletSecurity アノテーションは有効にならず、"/servlet1/servlet2" パスを保護できません。そのため、未承認アクセスが発生する可能性があります。
もし "/servlet1/servlet2" にアクセスする前に "/servlet1" にアクセスした場合、Tomcat は ACL をロードし、"/servlet1/servlet2" に対する保護を開始するため、脆弱性は発生しません。

Servlet1 の前に ServletSecurity アノテーションを追加し、Servlet2 にはこのアノテーションはありません。

web.xml ファイル内のサーブレットに対応する url-pattern を下図のように変更した後。

このプロジェクトを実行します。初めて servlet2 の URL にアクセスすると、未承認アクセスが可能であることがわかり、servlet1 に対する ACL は有効になりませんでした。

2回目に servlet1 の URL にアクセスすると、アクセスが禁止され、この時点で ACL が有効になります。

再度 servlet2 の URL にアクセスすると、アクセスが禁止されていることがわかりました。ACL が servlet2 に対して有効になるためには、servlet1 がアクセスされたことが前提条件となります。


そのため、脆弱性の再現は Tomcat の起動後、"/servlet1/" にアクセスする前に "/servlet1/servlet2/" ページにアクセスした場合に限られます。以前に誰かが "/servlet1/*" ページにアクセスした場合、脆弱性は発生しません。脆弱性の危険性は高いものの、利用条件が困難であるため、影響範囲は広くありません。