Apache Tomcat (CVE-2020-1938) および Undertow (CVE-2020-1745) での AJP ファイルの読み取り / インクルージョン
Environment
- Red Hat JBoss Web Server (JWS)
- 5.2.0
- 3.1.7
- Red Hat JBoss Enterprise Application Platform (EAP)
- 5.x
- 6.x
- 7.x
- Red Hat Enterprise Linux
- 5.x ELS
- 6.x
- 7.x
- 8.x (
pki-deps
モジュールのpki-servlet-container
、pki-servlet-engine
として)
Issue
-
CVE-2020-1938 は、Apache Tomcat の AJP コネクターを使用したファイルの読み取り / インクルージョンです。AJP プロトコルはデフォルトで有効になっており、AJP コネクターは TCP ポート
8009
をリッスンし、IP アドレス0.0.0.0
に結びつけられます。認証 / 信頼されていないリモート攻撃者は、この AJP 設定を悪用してサーバーから Web アプリケーションファイルを読み取り、信頼されていないクライアントに AJP ポートを公開する可能性があります。適切に設定されていないサーバーでファイルのアップロードが許可されている場合、攻撃者は悪意のある JavaServer Pages (JSP) コードをさまざまなファイルタイプ内にアップロードして、リモートコード実行 (RCE) を行う可能性があります。 -
CVE-2020-1745 は、Undertow の AJP コネクターを使用したファイルの読み取り / インクルージョンで、CVE-2020-1938 に非常に似ています。
Resolution
これは、Tomcat / Undertow の AJP プロトコルの設定に関する問題です。AJP は信頼性の高いプロトコルですが、信頼できないクライアントには公開しないでください。これは安全ではなく (クリアテキスト転送)、お客様のネットワークが安全であると想定しています。予防策として、AJP が公開されない設定を使用する必要があります。
優先順に示した以下の緩和策のいずれかを適用する必要があります。
- Tomcat で AJP を完全に無効にし、代わりに着信プロキシー接続に HTTP または HTTPS を使用します。 HTTP および HTTPS には、AJP と同じ信頼問題は含まれていません。
- AJP 接続をシークレットで保護し、ネットワークバインディングとファイアウォール設定を慎重に確認して、信頼できるホストからの受信接続のみが許可されるようにします。
- 信頼できるホストからの受信接続のみが許可されるようにするには、ネットワークバインディングとファイアウォール設定のみを使用してください。
AJP を無効にする最初のオプションは、最も安全で堅牢な推奨ソリューションです。シークレットを使用して AJP を保護すると、混乱が少なくなる可能性がありますが、secret
パラメーターをサポートする mod_jk
または httpd
のバージョンの 1 つを使用する必要があります。 このパラメーターは、Red Hat Enterprise Linux 7 および 8 の現行バージョンの httpd
でサポートされていますが、Red Hat Software Collections に含まれるバージョンは、このパラメーターをサポートしないため、別の軽減策を採用する必要があります。
さまざまな Red Hat 製品について、AJP を無効にする方法と AJP をシークレットで保護する方法に関する設定を以下に示します。
JWS (Tomcat)
-
お客様のサイトで AJP コネクターを 使用していない 場合は、
<TOMCAT_HOME>/conf/server.xml
ファイルから以下のようにコメントアウトして無効にします。<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
-
AJP コネクターが必要で、コメント / 非アクティブ化ができない場合は、AJP コンジットにシークレットパスワードを設定することをお勧めします - 同じシークレットキーワードを持つワーカーからのリクエストのみが受け入れられます。 Tomcat 側で
conf/server.xml
を編集します。<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" address="YOUR_TOMCAT_IP_ADDRESS" requiredSecret="YOUR_AJP_SECRET" />
YOUR_AJP_SECRET
は、安全性が高く簡単に推測できない値に変更する必要があることに留意してください。
JWS (Tomcat) OpenShift コンテナーイメージ
- JWS OpenShift コンテナーイメージ は、デフォルトでは AJP コネクターポート 8009 を公開しません。したがって、これらはこの脆弱性の影響を受けません。
JBoss EAP 5.2 (JBossWeb 2.1.x)
-
お客様のサイトで AJP コネクターを 使用していない 場合は、
<EAP52_HOME>/server/$PROFILE/deploy/jbossweb.sar/server.xml
ファイルから以下のようにコメントアウトして無効にします。<!-- <Connector protocol="AJP/1.3" port="8009" address="${jboss.bind.address}" redirectPort="8443" /> -->
-
AJP コネクターが必要で、コメント / 非アクティブ化ができない場合は、AJP コンジットにシークレットパスワードを設定することをお勧めします - 同じシークレットキーワードを持つワーカーからのリクエストのみが受け入れられます。 EAP 5.2 側で
<EAP52_HOME>/server/$PROFILE/deploy/jbossweb.sar/server.xml
を編集します。<Connector protocol="AJP/1.3" port="8009" address="${jboss.bind.address}" redirectPort="8443" requiredSecret="YOUR_AJP_SECRET"/>
YOUR_AJP_SECRET
は、安全性が高く簡単に推測できない値に変更する必要があることに留意してください。
JBoss EAP 6.4 (JBossWeb 7.x)
AJP コネクターは、 domain.xml
の standalone-full-ha.xml
、standalone-ha.xml
、および full-ha
、ha
プロファイルでのみデフォルトで有効になっています。 AJP コネクターは、以下のように安全性を確保できます。
-
JBoss EAP 6.4 Update 23+ で、または EAP 6.4 Update 22 に One off Patch を適用すると、脆弱性が修正され、カスタム AJP リクエスト属性はデフォルトでブロックされます。 カスタム AJP およびリクエスト属性を使用する場合は、デフォルトでは CVE 修正後は使用できないので、「How to allow custom AJP request attributes after applying the CVE-2020-1938 AJP File Read/Inclusion Vulnerability fix in JBoss EAP 6.4 Update 23+ or with the Security Patch applied to top of Update 22」を参照してください。
-
AJP を使用しない場合は、以下のように
enabled="false"
を設定するか、<connector name="AJP" .../>
部分全体をコメントアウトして、standalone-*.xml
やdomain.xml
ファイルで AJP ポートの設定を無効にすることができます。<connector name="AJP" protocol="AJP/1.3" scheme="http" socket-binding="ajp" enabled="false"/>
-
AJP コネクターが必須要件で、コメント化または非アクティブ化できない場合は、以下のシステムプロパティーを設定して、認証情報を AJP コネクターに追加することをお勧めします。システムプロパティーの追加に関する詳細は、こちらのナレッジ記事 も参照してください。
<system-properties> <property name="org.apache.coyote.ajp.DEFAULT_REQUIRED_SECRET" value="YOUR_AJP_SECRET"/> </system-properties>
YOUR_AJP_SECRET
は、安全性が高く簡単に推測できない値に変更する必要があることに留意してください。
JBoss EAP 7 (Undertow)
AJP は、 domain.xml
の standalone-full-ha.xml
、standalone-ha.xml
および full-ha
、ha
プロファイルでのみデフォルトで有効になっています。AJP コネクターは、以下のように安全性を確保できます。
-
JBoss EAP 7.2 Update 8+ で、または EAP 7.2 Update 7 / EAP 7.3 に One off Patch を適用すると、脆弱性が修正され、カスタム AJP リクエスト属性はデフォルトでブロックされます。 カスタム AJP およびリクエスト属性を使用する場合は、デフォルトでは CVE 修正後は使用できないので、「How to allow AJP request attributes after applying the CVE-2020-1745 AJP File Read/Inclusion Vulnerability fix in JBoss EAP 7.2 Update 8+」を参照してください。
-
AJP を使用しない場合は、以下のように
enabled="false"
を設定するか、<ajp-listener .../>
部分全体をコメントアウトして、standalone-*.xml
やdomain.xml
ファイルで AJP ポートの設定を無効にすることができます。<ajp-listener name="ajp" socket-binding="ajp" enabled="false"/>
重要:
mod_cluster
は、デフォルトでコンジットとして AJP を使用する点に留意してください。AJP コネクターを無効化する前に、AJP の代わりに HTTP または HTTPS を使用するようにmod_cluster
を設定する必要があります。 -
AJP コネクターが必須要件であり、コメント化または非アクティブ化できない場合は、Undertow サブシステム内で以下の設定を構成して、AJP リクエストの安全なリクエスト属性を確認します。
<subsystem xmlns="urn:jboss:domain:undertow:7.0" ...> ... <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <ajp-listener name="ajp" socket-binding="ajp"/> <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/> <host name="default-host" alias="localhost"> ... <!-- add the following with your AJP port (8009) --> <filter-ref name="secret-checker" predicate="equals(%p, 8009)"/> </host> </server> ... <filters> <!-- add the following with your credential (YOUR_AJP_SECRET) --> <expression-filter name="secret-checker" expression="not equals(%{r,secret}, 'YOUR_AJP_SECRET') -> response-code(403)"/> </filters> </subsystem>
上記の設定は、JBoss-CLI で以下の 2 つのコマンドを使用して追加できます。1
/subsystem=undertow/configuration=filter/expression-filter=secret-checker:add(expression="not equals(%{r,secret}, 'YOUR_AJP_SECRET') -> response-code(403)") /subsystem=undertow/server=default-server/host=default-host/filter-ref=secret-checker:add(predicate="equals(%p,8009)")
YOUR_AJP_SECRET
は、安全性が高く簡単に推測できない値に変更する必要があることに留意してください。
上記の設定が不可能な場合は、AJP ポートをループバックインターフェースにバインドするか、信頼できるホストからのアクセスのみを許可するファイアウォールを設定することで、ローカルユーザーまたは信頼できるユーザーへの攻撃対象領域を大幅に減らすことができます。
Apache httpd (JBCS または RHEL の httpd)
上記の「シークレット」設定が Tomcat / JBoss 側で設定されている場合、同じシークレット値 (上記の例では YOUR_AJP_SECRET
) をフロントエンドプロキシー (mod_proxy_ajp または mod_jk) で設定する必要があります。
Red Hat Software Collections (RHSCL) の httpd
は、secret
パラメーターをサポートしません。この場合、上記のように HTTP または HTTPS を使用し、Tomcat で AJP を無効化することを推奨しています。
mod_proxy (ajp を使用する mod_proxy_ajp / mod_proxy_balancer)
secret
プロパティーは、JBCS httpd 2.4.37、RHEL 7 httpd-2.4.6-672、RHEL 8 httpd-2.4.6-62 以降でサポートされています。mod_proxy_ajp
の場合、secret
プロパティーをProxyPass
設定に追加できます。mod_proxy_balancer
の場合、secret
プロパティーを各BalancerMember
設定に追加できます。
-
たとえば、
secret=YOUR_AJP_SECRET
を以下のように設定に追加します (例:<HTTPD_HOME>/conf/httpd.conf
または<HTTPD_HOME>/conf.d/proxy_ajp.conf
)。-
mod_proxy_ajp
:ProxyPass /example/ ajp://localhost:8009/example/ secret=YOUR_AJP_SECRET
-
mod_proxy_balancer
:<Proxy balancer://mycluster> BalancerMember ajp://node1:8009 route=node1 secret=YOUR_AJP_SECRET BalancerMember ajp://node2:8009 route=node2 secret=YOUR_AJP_SECRET </Proxy> ProxyPass /example/ balancer://mycluster/example/ stickysession=JSESSIONID|jsessionid
-
mod_jk
mod_jk
-secret
は、workers.properties
で、ワーカーまたはロードバランサーに指定できます。ロードバランサーにシークレットを設定すると、そのすべてのメンバーがこのシークレットを継承します。このsecret
プロパティーのサポートは、mod_jk 1.2.12 以降で追加されました。-
たとえば、
workers.properties
に以下を追加します。worker.<WORKER_NAME>.secret=YOUR_AJP_SECRET
WORKER_NAME を適切な名前に置き換える必要があることを確認します。
mod_cluster
mod_cluster
は、JBCS httpd 2.4.37 SP1 以前のsecret
プロパティー 3 をサポートしません。JBCS httpd 2.4.37 SP2 を使用すると、httpd mod_cluster 設定のAJPsecret
ディレクティブを AJP コネクターシークレットに一致するように設定できます。- 以前のバージョンで mod_cluster が必要な場合は、
ajp
の代わりにhttp
またはhttps
を使用するよう設定を変更する必要があります。これは、Tomcat / JBoss 側の AJP コネクターでsecret
が設定されている場合は、正しいシークレット値がないと接続できないからです。
RHEL 上の Tomcat
- Red Hat Enterprise Linux 8 では、Tomcat を
pki-deps
モジュールで利用できます。このモジュールは、pki-core
モジュールに同梱されている Dogtag Certificate System へのサポートに対してのみ使用することを目的としており、カスタムまたはサードパーティーのアプリケーションをホストするためのものではありません。この設定では、Tomcat はローカルでのみ使用できるため、リモート攻撃は不可能だと考えられています。そのため、重大度は中程度になります。 - Red Hat Enterprise Linux 7 および 6 が影響を受けます。 今後のアップデートについては、CVE ページを参照してください。
- Red Hat Enterprise Linux 5 は、サポートおよびメンテナンスライフサイクルの 延長ライフフェーズ に入っています。この脆弱性は中程度と評価されているため、延長ライフフェーズのサポート範囲ではなく、Red Hat Enterprise Linux 5 用の更新がリリースされる予定はありません。上記の軽減策を使用する必要があります。
- Red Hat Software Collections への影響はありません。
rh-java-common-tomcat
ソース RPM から生成されたバイナリーRPMには、手動で再コンパイルしない限り、この脆弱性の影響を受ける Apache Coyote コードは含まれていません。今後のアップデートでコードが修正される可能性があります。 - Red Hat Satellite 6 は、Red Hat Enterprise Linux 7 の tomcat を利用しています。Satellite バージョン 6.5 以前は、AJP を有効化します。これらのバージョンのユーザーは、RHSA-2020:0855 をインストールし、tomcat コンポーネントの修正バージョンを取得する必要があります。
Tomcat が組み込まれた Spring Boot
Tomcat が組み込まれた Spring Boot アプリケーションがある場合、組み込みアプリケーションコンテナーの作成を処理する Bean を定義する必要があります。この Bean は、AJP を使用して Apache を Tomcat に接続するコネクターを作成する必要があります。これを @Configuration 注釈付きクラスで以下のように定義できます。
@Configuration
public class TomcatConfig {
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
Connector ajpConnector = new Connector("org.apache.coyote.ajp.AjpNioProtocol");
AjpNioProtocol protocol= (AjpNioProtocol)ajpConnector.getProtocolHandler();
protocol.setSecret("myapjsecret");
ajpConnector.setPort(9090);
ajpConnector.setSecure(true);
tomcat.addAdditionalTomcatConnectors(ajpConnector);
return tomcat;
}
}
アプリを再起動すると、Tomcat がポート 8080 と 9090 の両方をリッスンしているというメッセージが表示されます。
[ restartedMain] org.apache.coyote.ajp.AjpNioProtocol : Initializing ProtocolHandler ["ajp-nio-127.0.0.1-9090"]
[ restartedMain] org.apache.coyote.ajp.AjpNioProtocol : Starting ProtocolHandler ["ajp-nio-127.0.0.1-9090"]
詳細なアップデートに関しては、CVE-2020-1938 および CVE-2020-1745 のページを参照してください。
Root Cause
この脆弱性は AJP プロトコル機能を利用してサーバー側のファイルにアクセスするものであり、コードエラーではありません。
AJP プロトコルを使用する場合は、有効なコンテンツのみを受け入れるために、適切なファイアウォールルールと秘密キーで正常に分離する必要があります。
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments