I have a Spring Boot application where I fill in a generated form based on a certain file that the user has to upload.
Somtimes in this file, a table can occur >100 times.
When this is the case, whenever I try to submit the form, I get the error:
More than the maximum number of request parameters (GET plus POST) for a single request ([10,000]) were detected. Any parameters beyond this limit have been ignored. To change this limit, set the maxParameterCount attribute on the Connector.
I have tried solving this by adding the following code to my server.xml:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" maxParameterCount="1000000"/>
As is stated in this post - set the maxParameterCount attribute on the Connector. But this doesn't seem to do anything.
My application is running on port 8081, but changing this in the connector code doesn't make any difference. I still get the error that my request exceeded 10 000 parameters.
Does anyone have an idea?
Thanks in advance.
Kind Regards
The third party tool we used for security test is giving Slow HTTP POST Vulnerability on Tomcat 8. We have a simple Spring Controller and JSP in the application.
Existing Tomcat connector config is below:
<Connector port="8643" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" compression="on"
clientAuth="false" sslProtocol="TLS" maxPostSize="20480"
maxSwallowSize="20480" maxHeaderCount="25" maxParameterCount="100"/>
Note that we don't have Apache or Nginx in front of tomcat. Please suggest the configs that we can use directly on Tomcat.
An example of Slow HTTP Attack is SLOWLORIS
To mitigate it with Tomcat, the solution is to use the NIO Connector, as explained in this tutorial.
What is unclear with your problem, is that Tomcat already uses the NIO connector by default on Tomcat 8, which is your configuration :
The default value is HTTP/1.1 which uses an auto-switching mechanism
to select either a non blocking Java NIO based connector or an
APR/native based connector.
Maybe should you set some other Connector parameters to specifically limit POST abuse, I suggest :
maxPostSize="1048576" (1 MByte)
connectionTimeout="10000" (10 seconds between the connection and the URI request)
disableUploadTimeout="false" (activate the POST maximum time allowed)
connectionUploadTimeout="20000" (maximum POST of 20 seconds)
An option is also to limit the headers number (default being 100), but this can have side effects with people using smartphones (which are known to send many headers) :
maxHeaderCount="25"
But it depends if your traffic is coming from Internet, or if it is a pro intranet with known users. In this latter case you could adjust the settings to be more permissive.
Edit 1: hardening with MultipartConfig
As stated on some other posts, maxPostSize might not work for limitting uploads. When using Java 7 built-in uploads, it is possible to configure limits by an annotation to the Servlet, or by configuration. It's not a pure Tomcat configuration as you asked, but it is necessary to know about it and talk with the DEV team as security must be taken in account since the early stages of development.
Edit 2: disabling chunked Transfer-Encoding
Some Slow HTTP POST attacks are based on requests sent with a Transfer-Encoding : chunked header, and then send many or an infinite number of chunks. To counter this attack, I suggest configuring a Rewrite Valve.
To achieve this, add the valve in your Host definition in server.xml :
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
Supposing your host name is the default one (localhost), you need to create $CATALINA_BASE/conf/Catalina/localhost/rewrite.config file with this content :
RewriteCond %{HTTP:Transfer-Encoding} chunked
RewriteRule ^(.*)$ / [F]
If necessary, you can adapt the RewriteRule to reply with something else than a 403 Forbidden which is due to the F flag. This is pure Tomcat config and flexible.
Request entity too large error, The requested resource does not allow request Data with GET(OR POST) Requests, or the amount of the data provided in the request exceeds the capacity limit.
I use tomcat 7 and apache in my project. I made changes in tomcat's server.xml as
<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" maxPostSize="-1" packetSize="65536"/>
still getting the same error.
I'm trying to resolve an issue about connecting Apache and Tomcat with mod_proxy_ajp. From reading I found that the problem might be the numbers of workers in the Apache and the Tomcat. So I try to find the worker's definition in the Tomcat but I couldnt find any. Can it be? Can Tomcat work without a workers.properties file? I checked the imports in the Tomcat conf just to make sure that there isnt a different file name but none. How can I find out the worker's configuration of my Tomcat setup? Is there a default?
The problem that I'm trying to solve is that in some cases the Tomcat stops responding to the Apache - in the Apache log I see many errors like:
1. "(70007)The timeout specified has expired: ajp_ilink_receive() can't receive header"
2. "ajp_read_header: ajp_ilink_receive failed"
3. "(120006)APR does not understand this error code: proxy: read response failed from 127.0.0.1:9005 (localhost)")
So I'm trying to find out maybe the Apache has more workers than the Tomcat.
I'm using Apache 2.2.15 and Tomcat 7, connected with mod_proxy ajp on a Redhat machine.
Any ideas?
Thanks!
Baba
On Tomcat side you have to configure AJP connector in server.xml, for example:
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443"/>
What is the maximum data size I can send in a single HttpURLConnection to Tomcat? Is there any limitation for the request size?
You have to modify two possible limits:
In conf\server.xml
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxPostSize="67589953" />
In webapps\manager\WEB-INF\web.xml
<multipart-config>
<!-- 52MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
The connector section has the parameter
maxPostSize
The maximum size in bytes of the POST which will be handled by the container FORM URL parameter parsing. The limit can be disabled by setting this attribute to a value less than or equal to 0. If not specified, this attribute is set to 2097152 (2 megabytes).
Another Limit is:
maxHttpHeaderSize The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 4096 (4 KB).
You find them in
$TOMCAT_HOME/conf/server.xml
The full answer
1. The default (fresh install of tomcat)
When you download tomcat from their official website (of today that's tomcat version 9.0.26), all the apps you installed to tomcat can handle HTTP requests of unlimited size, given that the apps themselves do not have any limits on request size.
However, when you try to upload an app in tomcat's manager app, that app has a default war file limit of 50MB. If you're trying to install Jenkins for example which is 77 MB as ot today, it will fail.
2. Configure tomcat's per port http request size limit
Tomcat itself has size limit for each port, and this is defined in conf\server.xml. This is controlled by maxPostSize attribute of each Connector(port). If this attribute does not exist, which it is by default, there is no limit on the request size.
To add a limit to a specific port, set a byte size for the attribute. For example, the below config for the default 8080 port limits request size to 200 MB. This means that all the apps installed under port 8080 now has the size limit of 200MB
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxPostSize="209715200" />
3. Configure app level size limit
After passing the port level size limit, you can still configure app level limit. This also means that app level limit should be less than port level limit. The limit can be done through annotation within each servlet, or in the web.xml file. Again, if this is not set at all, there is no limit on request size.
To set limit through java annotation
#WebServlet("/uploadFiles")
#MultipartConfig( fileSizeThreshold = 0, maxFileSize = 209715200, maxRequestSize = 209715200)
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) {
// ...
}
}
To set limit through web.xml
<web-app>
...
<servlet>
...
<multipart-config>
<file-size-threshold>0</file-size-threshold>
<max-file-size>209715200</max-file-size>
<max-request-size>209715200</max-request-size>
</multipart-config>
...
</servlet>
...
</web-app>
4. Appendix - If you see file upload size error when trying to install app through Tomcat's Manager app
Tomcat's Manager app (by default localhost:8080/manager) is nothing but a default web app. By default that app has a web.xml configuration of request limit of 50MB. To install (upload) app with size greater than 50MB through this manager app, you have to change the limit. Open the manager app's web.xml file from webapps\manager\WEB-INF\web.xml and follow the above guide to change the size limit and finally restart tomcat.
Although other answers include some of the following information, this is the absolute minimum that needs to be changed on EC2 instances, specifically regarding deployment of large WAR files, and is the least likely to cause issues during future updates. I've been running into these limits about every other year due to the ever-increasing size of the Jenkins WAR file (now ~72MB).
More specifically, this answer is applicable if you encounter a variant of the following error in catalina.out:
SEVERE [https-jsse-nio-8443-exec-17] org.apache.catalina.core.ApplicationContext.log HTMLManager:
FAIL - Deploy Upload Failed, Exception:
[org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException:
the request was rejected because its size (75333656) exceeds the configured maximum (52428800)]
On Amazon EC2 Linux instances, the only file that needs to be modified from the default installation of Tomcat (sudo yum install tomcat8) is:
/usr/share/tomcat8/webapps/manager/WEB-INF/web.xml
By default, the maximum upload size is exactly 50MB:
<multipart-config>
<!-- 50MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
There are only two values that need to be modified (max-file-size and max-request-size):
<multipart-config>
<!-- 100MB max -->
<max-file-size>104857600</max-file-size>
<max-request-size>104857600</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
When Tomcat is upgraded on these instances, the new version of the manager web.xml will be placed in web.xml.rpmnew, so any modifications to the original file will not be overwritten during future updates.
Just to add to the answers, App Server Apache Geronimo 3.0 uses Tomcat 7 as the web server, and in that environment the file server.xml is located at
<%GERONIMO_HOME%>/var/catalina/server.xml.
The configuration does take effect even when the Geronimo Console at Application Server->WebServer->TomcatWebConnector->maxPostSize still displays 2097152 (the default value)