Discussion:
maxParameterCount not applied to multipart requests
Kanatoko
2012-05-05 11:25:58 UTC
Permalink
Hello list,

It seems that the Connector attribute "maxParameterCount" is not applied
to multipart requests.
(And, the default value is -1, maybe it should be 10000.)

Tested version: Tomcat 7 trunk

Thanks.
--
Kanatoko
http://www.jumperz.net/
Mark Thomas
2012-05-06 09:05:24 UTC
Permalink
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount" is not applied
to multipart requests.
Correct. This is by design.
Post by Kanatoko
(And, the default value is -1, maybe it should be 10000.)
Wrong. The default is 10000, as per the documentation.
Post by Kanatoko
Tested version: Tomcat 7 trunk
Clearly not. If you had tested this you would have found that the limit
was indeed 10000.

Mark
Christopher Schultz
2012-05-07 21:02:40 UTC
Permalink
Mark,
Post by Mark Thomas
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount" is not
applied to multipart requests.
Correct. This is by design.
Doesn't that make it trivial to launch a DOS on a server by simply
using multipart/form-data?

Why not limit parameters for multipart messages?

- -chris
André Warnier
2012-05-07 21:10:50 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Mark,
Post by Mark Thomas
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount" is not
applied to multipart requests.
Correct. This is by design.
Doesn't that make it trivial to launch a DOS on a server by simply
using multipart/form-data?
Why not limit parameters for multipart messages?
Impish guess : because "by design" means that it is a lot harder to go dig into the code
borrowed from Commons/FileUpload and to modify it to find out and limit the number of
parameters ?
(and probably a "patches welcome" to follow)
Mark Thomas
2012-05-07 21:21:46 UTC
Permalink
Post by André Warnier
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Mark,
Post by Mark Thomas
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount" is not
applied to multipart requests.
Correct. This is by design.
Doesn't that make it trivial to launch a DOS on a server by simply
using multipart/form-data?
Only if the application does something stupid which would make it an
application issue not a Tomcat one.

Tomcat only processes these requests for Servlet 3.0 file upload and
there are already sufficient limits in place for that case to prevent a DoS.
Post by André Warnier
Why not limit parameters for multipart messages?
Impish guess : because "by design" means that it is a lot harder to go
dig into the code borrowed from Commons/FileUpload and to modify it to
find out and limit the number of parameters ?
(and probably a "patches welcome" to follow)
Nope. See above.

Mark
Christopher Schultz
2012-05-07 21:26:28 UTC
Permalink
Mark,
Post by Mark Thomas
Tomcat only processes these requests for Servlet 3.0 file upload
and there are already sufficient limits in place for that case to
prevent a DoS.
Aah, right: multipart is only supported if the servlet has been marked
as such, and therefore the developer knows to expect large mounts of
data (and can configure such limits).

The wildcard is the "casual multipart parsing" which allows any
multipart request to be parsed without regard for such limits. Any
limits (data size) imposed on the connector will be used in those
cases, but "maximum number of parameters" is not one of them. I should
probably update the documentation for that feature to make a note of
this caveat.

Thanks,
- -chris
Kanatoko
2012-05-08 07:27:14 UTC
Permalink
I had some tests on a servlet with @MultipartConfig and getParts()
and find that the hash collision attack was still in place.

Parameters like below cause the problem.
*********************************************************
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyEyEyEy"

1
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyEyEyFZ"

1
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyEyFZEy"

1
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyEyFZFZ"

1
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyFZEyEy"

1
--abc
Content-Disposition: form-data; name="EyEyEyEyEyEyEyEyEyEyEyEyFZEyFZ"

1
(repeat)
*********************************************************

As I wrote, the number of parameters is not limited to 10000.

Thanks.
--
Kanatoko
http://www.jumperz.net/
André Warnier
2012-05-08 09:28:20 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Mark,
Post by Mark Thomas
Tomcat only processes these requests for Servlet 3.0 file upload
and there are already sufficient limits in place for that case to
prevent a DoS.
Aah, right: multipart is only supported if the servlet has been marked
as such, and therefore the developer knows to expect large mounts of
data (and can configure such limits).
The wildcard is the "casual multipart parsing" which allows any
multipart request to be parsed without regard for such limits. Any
limits (data size) imposed on the connector will be used in those
cases, but "maximum number of parameters" is not one of them. I should
probably update the documentation for that feature to make a note of
this caveat.
From the documentation of Commons/fileUpload, it would seem rather simple - for a Java
guru - to implement a counter while processing the POSTed parameters, and ignore what is
above maxParameterCount :

Sample code from http://commons.apache.org/fileupload/using.html :

// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();

if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}

(Maybe the "items" object above already has a "size" or "length" method, avoiding the
counter logic altogether)

Of course by then, the POST has already been parsed, so I don't know if this would help a
lot to avoid a DOS attack.
But the maximum acceptable total size of the POST can be specified in advance, to avoid
this. After all, if someone wants to allow POSTs with 10,000 small parameters, then why not ?

I do not understand on the other hand the OP's later reference to a "hash collision".
That sounds like a JVM issue, rather than a specifically Tomcat one, no ?
Mark Thomas
2012-05-08 09:56:16 UTC
Permalink
Post by André Warnier
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Mark,
Post by Mark Thomas
Tomcat only processes these requests for Servlet 3.0 file upload
and there are already sufficient limits in place for that case to
prevent a DoS.
Aah, right: multipart is only supported if the servlet has been marked
as such, and therefore the developer knows to expect large mounts of
data (and can configure such limits).
The wildcard is the "casual multipart parsing" which allows any
multipart request to be parsed without regard for such limits. Any
limits (data size) imposed on the connector will be used in those
cases, but "maximum number of parameters" is not one of them. I should
probably update the documentation for that feature to make a note of
this caveat.
From the documentation of Commons/fileUpload, it would seem rather
simple - for a Java guru - to implement a counter while processing the
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}
(Maybe the "items" object above already has a "size" or "length" method,
avoiding the counter logic altogether)
Of course by then, the POST has already been parsed, so I don't know if
this would help a lot to avoid a DOS attack.
But the maximum acceptable total size of the POST can be specified in
advance, to avoid this. After all, if someone wants to allow POSTs with
10,000 small parameters, then why not ?
I do not understand on the other hand the OP's later reference to a
"hash collision". That sounds like a JVM issue, rather than a
specifically Tomcat one, no ?
It is a JVM issue (in my view and many others) but one Oracle has chosen
not to fix.

maxParameterCount was put in place as a mitigation for this issue. It
looks like the OP may have a valid point regarding multi-part requests -
at least as far as the Servlet 3.0 upload code is concerned. I need to
do review the code to see exactly what is going on. Outside of Servlet
3.0 file upload, I don't believe it is a Tomcat concern.

Mark
Mark Thomas
2012-05-08 20:08:06 UTC
Permalink
Post by Mark Thomas
Post by André Warnier
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Mark,
Post by Mark Thomas
Tomcat only processes these requests for Servlet 3.0 file upload
and there are already sufficient limits in place for that case to
prevent a DoS.
Aah, right: multipart is only supported if the servlet has been marked
as such, and therefore the developer knows to expect large mounts of
data (and can configure such limits).
The wildcard is the "casual multipart parsing" which allows any
multipart request to be parsed without regard for such limits. Any
limits (data size) imposed on the connector will be used in those
cases, but "maximum number of parameters" is not one of them. I should
probably update the documentation for that feature to make a note of
this caveat.
From the documentation of Commons/fileUpload, it would seem rather
simple - for a Java guru - to implement a counter while processing the
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}
(Maybe the "items" object above already has a "size" or "length" method,
avoiding the counter logic altogether)
Of course by then, the POST has already been parsed, so I don't know if
this would help a lot to avoid a DOS attack.
But the maximum acceptable total size of the POST can be specified in
advance, to avoid this. After all, if someone wants to allow POSTs with
10,000 small parameters, then why not ?
I do not understand on the other hand the OP's later reference to a
"hash collision". That sounds like a JVM issue, rather than a
specifically Tomcat one, no ?
It is a JVM issue (in my view and many others) but one Oracle has chosen
not to fix.
maxParameterCount was put in place as a mitigation for this issue. It
looks like the OP may have a valid point regarding multi-part requests -
at least as far as the Servlet 3.0 upload code is concerned. I need to
do review the code to see exactly what is going on.
Yep, a one line fix was required. Fixed in trunk and 7.0.x and will be
in 7.0.28 omwards.

Mark
Kanatoko
2012-05-09 02:51:11 UTC
Permalink
Post by Mark Thomas
Yep, a one line fix was required. Fixed in trunk and 7.0.x and will be
in 7.0.28 omwards.
Mark
I have confirmed that this issue is fixed in tomcat 7 trunk.
Thank you Mark.
--
Kanatoko
http://www.jumperz.net/
Christopher Schultz
2012-05-07 21:22:32 UTC
Permalink
André,
Post by André Warnier
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Mark,
Post by Mark Thomas
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount" is
not applied to multipart requests.
Correct. This is by design.
Doesn't that make it trivial to launch a DOS on a server by
simply using multipart/form-data?
Why not limit parameters for multipart messages?
Impish guess : because "by design" means that it is a lot harder to
go dig into the code borrowed from Commons/FileUpload and to modify
it to find out and limit the number of parameters ?
Probably not: commons-fileupload isn't a dependency of Tomcat, at
least not in trunk. Tomcat performs its own multipart handling in
o.a.c.connector.Request.parseParts.

- -chris
Mark Thomas
2012-05-07 21:25:12 UTC
Permalink
Post by Christopher Schultz
André,
Post by André Warnier
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Mark,
Post by Mark Thomas
Post by Kanatoko
Hello list,
It seems that the Connector attribute "maxParameterCount"
is not applied to multipart requests.
Correct. This is by design.
Doesn't that make it trivial to launch a DOS on a server by
simply using multipart/form-data?
Why not limit parameters for multipart messages?
Impish guess : because "by design" means that it is a lot harder
to go dig into the code borrowed from Commons/FileUpload and to
modify it to find out and limit the number of parameters ?
Probably not: commons-fileupload isn't a dependency of Tomcat, at
least not in trunk. Tomcat performs its own multipart handling in
o.a.c.connector.Request.parseParts.
That is a packaged renamed fork of commons file upload.

Mark
Loading...