Author: markt
Date: Thu Aug 11 17:09:25 2016
New Revision: 1756013

URL: http://svn.apache.org/viewvc?rev=1756013&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=59904
Add a limit (default 200) for the number of cookies allowed per request.
Based on a patch by gehui.

Modified:
    tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
    tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
    tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
    tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
    tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookies.java
    tomcat/trunk/webapps/docs/changelog.xml
    tomcat/trunk/webapps/docs/config/ajp.xml
    tomcat/trunk/webapps/docs/config/http.xml

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java Thu Aug 11 
17:09:25 2016
@@ -46,6 +46,8 @@ public abstract class AbstractProcessor
     protected final Response response;
     protected volatile SocketWrapperBase<?> socketWrapper = null;
     protected volatile SSLSupport sslSupport;
+    private int maxCookieCount = 200;
+
 
     /**
      * Error state for the request/response currently being processed.
@@ -286,6 +288,16 @@ public abstract class AbstractProcessor
     }
 
 
+    public int getMaxCookieCount() {
+        return maxCookieCount;
+    }
+
+
+    public void setMaxCookieCount(int maxCookieCount) {
+        this.maxCookieCount = maxCookieCount;
+    }
+
+
     @Override
     public void recycle() {
         errorState = ErrorState.NONE;

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Thu Aug 11 
17:09:25 2016
@@ -103,6 +103,13 @@ public abstract class AbstractProtocol<S
     private AsyncTimeout asyncTimeout = null;
 
 
+    /**
+     * The maximum number of cookies permitted for a request. Use a value less
+     * than zero for no limit. Defaults to 200.
+     */
+    private int maxCookieCount = 200;
+
+
     public AbstractProtocol(AbstractEndpoint<S> endpoint) {
         this.endpoint = endpoint;
         setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
@@ -201,6 +208,16 @@ public abstract class AbstractProtocol<S
     }
 
 
+    public int getMaxCookieCount() {
+        return maxCookieCount;
+    }
+
+
+    public void setMaxCookieCount(int maxCookieCount) {
+        this.maxCookieCount = maxCookieCount;
+    }
+
+
     // ---------------------- Properties that are passed through to the 
EndPoint
 
     @Override

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Thu Aug 11 
17:09:25 2016
@@ -192,6 +192,7 @@ public abstract class AbstractAjpProtoco
         processor.setRequiredSecret(requiredSecret);
         processor.setKeepAliveTimeout(getKeepAliveTimeout());
         processor.setClientCertProvider(getClientCertProvider());
+        processor.setMaxCookieCount(getMaxCookieCount());
         return processor;
     }
 

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Thu Aug 11 
17:09:25 2016
@@ -1045,6 +1045,7 @@ public class AjpProcessor extends Abstra
 
         // Set this every time in case limit has been changed via JMX
         headers.setLimit(endpoint.getMaxHeaderCount());
+        request.getCookies().setLimit(getMaxCookieCount());
 
         boolean contentLengthSet = false;
         int hCount = requestHeaderMessage.getInt();

Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Thu 
Aug 11 17:09:25 2016
@@ -648,6 +648,7 @@ public abstract class AbstractHttp11Prot
         processor.setMaxSavePostSize(getMaxSavePostSize());
         processor.setServer(getServer());
         
processor.setServerRemoveAppProvidedValues(getServerRemoveAppProvidedValues());
+        processor.setMaxCookieCount(getMaxCookieCount());
         return processor;
     }
 

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Thu Aug 11 
17:09:25 2016
@@ -1007,6 +1007,7 @@ public class Http11Processor extends Abs
                     keptAlive = true;
                     // Set this every time in case limit has been changed via 
JMX
                     
request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
+                    request.getCookies().setLimit(getMaxCookieCount());
                     if (!inputBuffer.parseHeaders()) {
                         // We've read part of the request, don't recycle it
                         // instead associate it with the socket

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/LocalStrings.properties Thu 
Aug 11 17:09:25 2016
@@ -28,8 +28,9 @@ parameters.fallToDebug=\n Note: further
 cookies.invalidCookieToken=Cookies: Invalid cookie. Value not a token or 
quoted value
 cookies.invalidSpecial=Cookies: Unknown Special Cookie
 cookies.fallToDebug=\n Note: further occurrences of Cookie errors will be 
logged at DEBUG level.
+cookies.maxCountFail=More than the maximum allowed number of cookies, [{0}], 
were detected.
 
-headers.maxCountFail=More than the maximum allowed number of headers ([{0}]) 
were detected.
+headers.maxCountFail=More than the maximum allowed number of headers, [{0}], 
were detected.
 
 rfc6265CookieProcessor.invalidCharInValue=An invalid character [{0}] was 
present in the Cookie value
 rfc6265CookieProcessor.invalidDomain=An invalid domain [{0}] was specified for 
this cookie

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookies.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookies.java?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookies.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookies.java Thu Aug 11 
17:09:25 2016
@@ -16,14 +16,19 @@
  */
 package org.apache.tomcat.util.http;
 
+import org.apache.tomcat.util.res.StringManager;
+
 /**
  * This class is not thread-safe.
  */
 public class ServerCookies {
 
+    StringManager sm = StringManager.getManager(ServerCookies.class);
+
     private ServerCookie[] serverCookies;
 
     private int cookieCount = 0;
+    private int limit = 200;
 
 
     public ServerCookies(int initialSize) {
@@ -38,8 +43,14 @@ public class ServerCookies {
      * @return the new cookie
      */
     public ServerCookie addCookie() {
+        if (limit > -1 && cookieCount >= limit) {
+            throw new IllegalArgumentException(
+                    sm.getString("cookies.maxCountFail", 
Integer.valueOf(limit)));
+        }
+
         if (cookieCount >= serverCookies.length) {
-            ServerCookie scookiesTmp[] = new ServerCookie[2*cookieCount];
+            int newSize = Math.min(2*cookieCount, limit);
+            ServerCookie scookiesTmp[] = new ServerCookie[newSize];
             System.arraycopy(serverCookies, 0, scookiesTmp, 0, cookieCount);
             serverCookies = scookiesTmp;
         }
@@ -64,6 +75,17 @@ public class ServerCookies {
     }
 
 
+    public void setLimit(int limit) {
+        this.limit = limit;
+        if (limit > -1 && serverCookies.length > limit && cookieCount <= 
limit) {
+            // shrink cookie list array
+            ServerCookie scookiesTmp[] = new ServerCookie[limit];
+            System.arraycopy(serverCookies, 0, scookiesTmp, 0, cookieCount);
+            serverCookies = scookiesTmp;
+        }
+    }
+
+
     public void recycle() {
         for (int i = 0; i < cookieCount; i++) {
             serverCookies[i].recycle();

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Aug 11 17:09:25 2016
@@ -138,6 +138,10 @@
         (remm)
       </fix>
       <fix>
+        <bug>59904</bug>: Add a limit (default 200) for the number of cookies
+        allowed per request. Based on a patch by gehui. (markt)
+      </fix>
+      <fix>
         <bug>59925</bug>: Correct regression in r1628368 and ensure that HTTP
         separators are handled as configured in the
         <code>LegacyCookieProcessor</code>. Patch provided by Kyohei Nakamura.

Modified: tomcat/trunk/webapps/docs/config/ajp.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/ajp.xml?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/ajp.xml (original)
+++ tomcat/trunk/webapps/docs/config/ajp.xml Thu Aug 11 17:09:25 2016
@@ -386,6 +386,12 @@
       and connections are not counted.</p>
     </attribute>
 
+    <attribute name="maxCookieCount" required="false">
+      <p>The maximum number of cookies that are permitted for a request. A 
value
+      of less than zero means no limit. If not specified, a default value of 
200
+      will be used.</p>
+    </attribute>
+
     <attribute name="maxThreads" required="false">
       <p>The maximum number of request processing threads to be created
       by this <strong>Connector</strong>, which therefore determines the

Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1756013&r1=1756012&r2=1756013&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Thu Aug 11 17:09:25 2016
@@ -453,6 +453,12 @@
       and connections are not counted.</p>
     </attribute>
 
+    <attribute name="maxCookieCount" required="false">
+      <p>The maximum number of cookies that are permitted for a request. A 
value
+      of less than zero means no limit. If not specified, a default value of 
200
+      will be used.</p>
+    </attribute>
+
     <attribute name="maxExtensionSize" required="false">
       <p>Limits the total length of chunk extensions in chunked HTTP requests.
       If the value is <code>-1</code>, no limit will be imposed. If not



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to