How can I limit the size of HTTP POST requests in mod_perl?
Asked Answered
C

2

8

I'm working on a page which accepts file uploads. In theory, I can detect when the file they're sending me is too big (by looking at the Content-Length of their response), and refuse to accept the upload, returning an HTTP 413 "Request Entity Too Large" error.

However, it seems that simply doing that is not enough -- Firefox, at least, will still keep sending the rest of the file (which could take a Long Time), before it shows my error page.

The HTTP spec says that I: "MAY close the connection to prevent the client from continuing the request." However, doing either a 'close STDIN', 'shutdown STDIN, 0', or some variant of that does not seem to do the trick -- Firefox still keeps sending the file.

I suspect that, when my mod_perl handler closes the connection, it's just closing the connection between itself and Apache; Apache keeps the connection between it and the client alive. Is there some way to tell Apache to shut down the connection? Otherwise, this seems like a great DoS vector.

Any suggestions would be welcome.

Contrabandist answered 11/12, 2009 at 20:15 Comment(1)
You might also want to think about the request being chunked, and so you won't know the size of the request body until all chunks have arrived...Prepense
R
7

Have you explored Apache's limitation capabilities (as opposed to Perl's)? I don't know in details how the LimitRequestBody directive deals with requests that too large, but at least in theory it looks like a setting designed to block off attacks.

Rammer answered 11/12, 2009 at 20:21 Comment(0)
J
2

Yes, it doesn't matter what Perl does with STDIN or STDOUT, Apache will still allow the upload to proceed before it even checks what happens with your CGI. You can close STDIN or STDOUT or even exit() (although you can't do that since your process is persistent), but none of that will have any effect until after Apache is done accepting the POST request in its entirety. Likewise with any kind of status headers you might generate, such as a 413 for "Request too large".

Hence, you need to have Apache refuse POST requests beyond a certain size for this to work, for example using LimitRequestBody as suggested by Pekka.

Judaism answered 11/12, 2009 at 21:12 Comment(3)
mod_cgi and mod_perl are different modules.Olag
@Alexandr: Yes... ? I'm sorry, I don't follow.Judaism
I think what he meant is that in mod_perl, you can have a handler fire BEFORE the post has been completed. This allows you to cancel the post while its in progress as opposed to waiting until the download is completed.Corroboree

© 2022 - 2024 — McMap. All rights reserved.