如何限制 mod_perl 中 HTTP POST 请求的大小?
我正在开发一个接受文件上传的页面。理论上我可以 检测他们发送给我的文件何时太大(通过查看 他们的回复的内容长度),并拒绝接受上传, 返回 HTTP 413“请求实体太大”错误。
然而,似乎仅仅这样做还不够——Firefox,位于 至少,仍然会继续发送文件的其余部分(这可能需要 很长时间),然后才显示我的错误页面。
HTTP 规范说我:“可以关闭连接以防止客户端 继续请求。”但是,执行“关闭 STDIN”, “shutdown STDIN, 0”或它的某些变体似乎不起作用 技巧——Firefox 仍然继续发送文件。
我怀疑,当我的 mod_perl 处理程序关闭连接时,它是 只是关闭它自己和 Apache 之间的连接;阿帕奇保留了 它和客户端之间的连接仍然有效。有什么办法可以告诉 Apache要关闭连接吗?否则,这看起来很棒 DoS 向量。
任何建议都将受到欢迎。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否探索过 Apache 的限制功能(相对于 Perl 的限制功能)?我不详细了解
LimitRequestBody
指令处理太大的请求,但至少在理论上它看起来像是一个旨在阻止攻击的设置。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.是的,无论 Perl 对
STDIN
或STDOUT
做什么,Apache 仍然会在检查 CGI 发生的情况之前允许上传继续进行。您可以关闭STDIN
或STDOUT
甚至exit()
(尽管您不能这样做,因为您的进程是持久的),但没有一个直到 Apache 完全接受 POST 请求之后,该命令才会生效。同样,对于您可能生成的任何类型的状态标头,例如表示“请求太大”的413
。因此,您需要让 Apache 拒绝超过一定大小的 POST 请求才能正常工作,例如使用
LimitRequestBody
作为 佩卡建议。Yes, it doesn't matter what Perl does with
STDIN
orSTDOUT
, Apache will still allow the upload to proceed before it even checks what happens with your CGI. You can closeSTDIN
orSTDOUT
or evenexit()
(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 a413
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.