This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 2e108583e8665fdc61970137a409f15c4df3a36f Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Jan 21 15:04:12 2020 +0000 Add new AJP attribute allowedArbitraryRequestAttribute Requests with unrecognised attributes will be blocked with a 403 --- java/org/apache/coyote/ajp/AbstractAjpProtocol.java | 13 +++++++++++++ java/org/apache/coyote/ajp/AjpProcessor.java | 20 +++++++++++++++++++- webapps/docs/config/ajp.xml | 19 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java index 81da7da..a2f5e28 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 abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { } + 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 128c1a0..226d210 100644 --- a/java/org/apache/coyote/ajp/AjpProcessor.java +++ b/java/org/apache/coyote/ajp/AjpProcessor.java @@ -28,6 +28,8 @@ import java.security.cert.X509Certificate; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import jakarta.servlet.http.HttpServletResponse; @@ -742,12 +744,28 @@ public class AjpProcessor extends AbstractProcessor { } } 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 (jakartaAttributeMapping.containsKey(n)) { // AJP uses the Java Servlet attribute names. // Need to convert these to Jakarta SAervlet. request.setAttribute(jakartaAttributeMapping.get(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 3999a13..69348a1 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 --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org