Projects
Eulaceura:Mainline:GA
tomcat
_service:obs_scm:CVE-2020-1938-3.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2020-1938-3.patch of Package tomcat
From 64fa5b99442589ef0bf2a7fcd71ad2bc68b35fad Mon Sep 17 00:00:00 2001 From: Mark Thomas <markt@apache.org> Date: Tue, 21 Jan 2020 15:04:12 +0000 Subject: [PATCH] Add new AJP attribute allowedArbitraryRequestAttributes Requests with unrecognised attributes will be blocked with a 403 --- .../coyote/ajp/AbstractAjpProtocol.java | 13 +++++++ java/org/apache/coyote/ajp/AjpProcessor.java | 36 ++++++++++++++++++- webapps/docs/config/ajp.xml | 19 ++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java index 81da7da6d1..a2f5e2844a 100644 --- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java +++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java @@ -17,6 +17,7 @@ package org.apache.coyote.ajp; import java.net.InetAddress; +import java.util.regex.Pattern; import org.apache.coyote.AbstractProtocol; import org.apache.coyote.Processor; @@ -188,6 +189,18 @@ public boolean getSecretRequired() { } + private Pattern allowedArbitraryRequestAttributesPattern; + public void setAllowedArbitraryRequestAttributes(String allowedArbitraryRequestAttributes) { + this.allowedArbitraryRequestAttributesPattern = Pattern.compile(allowedArbitraryRequestAttributes); + } + public String getAllowedArbitraryRequestAttributes() { + return allowedArbitraryRequestAttributesPattern.pattern(); + } + protected Pattern getAllowedArbitraryRequestAttributesPattern() { + return allowedArbitraryRequestAttributesPattern; + } + + /** * AJP packet size. */ diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java index d466de2c09..f3d783f546 100644 --- a/java/org/apache/coyote/ajp/AjpProcessor.java +++ b/java/org/apache/coyote/ajp/AjpProcessor.java @@ -25,6 +25,11 @@ import java.security.NoSuchProviderException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.http.HttpServletResponse; @@ -78,6 +83,9 @@ private static final byte[] pongMessageArray; + private static final Set<String> javaxAttributes; + + static { // Allocate the end message array AjpMessage endMessage = new AjpMessage(16); @@ -118,6 +126,14 @@ pongMessageArray = new byte[pongMessage.getLen()]; System.arraycopy(pongMessage.getBuffer(), 0, pongMessageArray, 0, pongMessage.getLen()); + + // Build the Set of javax attributes + Set<String> s = new HashSet<>(); + s.add("javax.servlet.request.cipher_suite"); + s.add("javax.servlet.request.key_size"); + s.add("javax.servlet.request.ssl_session"); + s.add("javax.servlet.request.X509Certificate"); + javaxAttributes= Collections.unmodifiableSet(s); } @@ -728,8 +744,26 @@ private void prepareRequest() { } } else if(n.equals(Constants.SC_A_SSL_PROTOCOL)) { request.setAttribute(SSLSupport.PROTOCOL_VERSION_KEY, v); + } else if (n.equals("JK_LB_ACTIVATION")) { + request.setAttribute(n, v); + } else if (javaxAttributes.contains(n)) { + request.setAttribute(n, v); } else { - request.setAttribute(n, v ); + // All 'known' attributes will be processed by the previous + // blocks. Any remaining attribute is an 'arbitrary' one. + Pattern pattern = protocol.getAllowedArbitraryRequestAttributesPattern(); + if (pattern == null) { + response.setStatus(403); + setErrorState(ErrorState.CLOSE_CLEAN, null); + } else { + Matcher m = pattern.matcher(n); + if (m.matches()) { + request.setAttribute(n, v); + } else { + response.setStatus(403); + setErrorState(ErrorState.CLOSE_CLEAN, null); + } + } } break; diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml index 3999a13e66..69348a18e2 100644 --- a/webapps/docs/config/ajp.xml +++ b/webapps/docs/config/ajp.xml @@ -311,6 +311,25 @@ port. By default, the loopback address will be used.</p> </attribute> + <attribute name="allowedArbitraryRequestAttributes" required="false"> + <p>The AJP protocol passes some information from the reverse proxy to the + AJP connector using request attributes. These attributes are:</p> + <ul> + <li>javax.servlet.request.cipher_suite</li> + <li>javax.servlet.request.key_size</li> + <li>javax.servlet.request.ssl_session</li> + <li>javax.servlet.request.X509Certificate</li> + <li>AJP_LOCAL_ADDR</li> + <li>AJP_REMOTE_PORT</li> + <li>AJP_SSL_PROTOCOL</li> + <li>JK_LB_ACTIVATION</li> + </ul> + <p>The AJP protocol supports the passing of arbitrary request attributes. + Requests containing arbitrary request attributes will be rejected with a + 403 response unless the entire attribute name matches this regular + expression. If not specified, the default value is <code>null</code>.</p> + </attribute> + <attribute name="bindOnInit" required="false"> <p>Controls when the socket used by the connector is bound. By default it is bound when the connector is initiated and unbound when the connector is
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2