You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/02/04 18:47:39 UTC
[tomcat] 04/05: Add new AJP attribute
allowedArbitraryRequestAttributes
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 64fa5b99442589ef0bf2a7fcd71ad2bc68b35fad
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Jan 21 15:04:12 2020 +0000
Add new AJP attribute allowedArbitraryRequestAttributes
Requests with unrecognised attributes will be blocked with a 403
---
.../org/apache/coyote/ajp/AbstractAjpProtocol.java | 13 ++++++++
java/org/apache/coyote/ajp/AjpProcessor.java | 36 +++++++++++++++++++++-
webapps/docs/changelog.xml | 5 +++
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 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 d466de2..f3d783f 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -25,6 +25,11 @@ import java.nio.ByteBuffer;
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 @@ public class AjpProcessor extends AbstractProcessor {
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 @@ public class AjpProcessor extends AbstractProcessor {
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 @@ 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 (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/changelog.xml b/webapps/docs/changelog.xml
index 5d0cf7e..46fa42f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -190,6 +190,11 @@
will not start unless the <code>secret</code> attribute is configured to
a non-null, non-zero length String. (markt)
</add>
+ <add>
+ Add a new attribute, <code>allowedArbitraryRequestAttributes</code> to
+ the AJP/1.3 Connector. Requests with unreconised attributes will be
+ blocked with a 403. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Jasper">
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org