如何防止表单在 5 分钟内提交多次?
我最近发现我的 PM 系统存在一个巨大的安全问题,该系统允许用户通过地址栏中的 for
循环发送任意数量的消息。有人将其放入地址栏:
javascript:for(x=0;x<10000;x++){ $('#compose form').submit(); }
该消息已发送给我 1000 次,而我的收件箱充满了相同的消息,而且我的数据库已满,以至于 phpMyAdmin 非常缓慢。
我的问题是,我该如何防止这种情况发生?这是一个主要问题。
此外,表单是通过 AJAX 提交的。
编辑:
我使用 PHP,那么如何防止这种情况发生呢?就像我怎样才能做到每 5 分钟左右只能发送一条消息,如果他们在 5 分钟内提交多条消息,它将显示错误(或者根本不显示任何用户反馈,只是阻止其提交) )?
I recently found a huge security problem with my PM system that allows users to send a message as much as they want with a for
loop in the address bar. Someone put this into the address bar:
javascript:for(x=0;x<10000;x++){ $('#compose form').submit(); }
And the message was sent 1000 times to me and my inbox was full of the same message and my database was so full that phpMyAdmin was being very laggy.
My question is, how can I prevent this? This is a major issue.
Also, the form is submitted with AJAX.
Edit:
I use PHP, so how can I prevent this? Like how could I make it to where a message can only be sent every 5 minutes or so and if they submit more than one within 5 minutes it will display an error (or not show any user feedback at all and just stop it from being submitted)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有一种明显的方法可以修复它,并且问题不在于客户端 - 它在于服务器端。
您的服务器脚本不应允许过于频繁地发送消息 - 例如。通常每 10 分钟一次。为此,您可以在服务器端使用会话机制,并在用户发送电子邮件时保存信息。如果用户尚未发送电子邮件,您还应该将该信息保存在会话中 - 以区分启用会话的人和禁用会话的人(并且您应该完全阻止后者发送电子邮件)。
会话的实现方式(具体代码)取决于您用于服务器端脚本的语言(PHP、Python、JSP 等)。
There is one obvious way to fix it and the problem lies not on the client side - it lies on the server side.
Your server script should not allow sending messages too often - eg. often than, say, once each 10 minutes. To do it you can use session mechanism on the server side and save the information when the user sent the email. If user has not sent an email, you should also save that information in session - to distinguish people with session enabled from people with session disabled (and you should block the latter from sending emails at all).
The way session should be implemented (the specific code) depends on the language you use for server side scripting (PHP, Python, JSP etc.).
如果有人知道对您执行此操作,您可能无法在客户端执行任何操作,因此我想说的唯一选择是您记录或保留请求数量(可能针对特定资源)的计数等,并且拒绝特定用户的请求(或发送“繁忙”http 代码等)。
我认为最简单的方法是计算来自特定 IP 地址的请求(这显然有缺点,例如代理或 NAT 后面的多个用户等)。
实际的解决方案将取决于您的服务器端语言和 Web 服务器,但您也许可以制定一个规则并看看它是如何工作的。每个 IP 地址每分钟 5 个请求(或适合您的使用的任何请求)。
If someone has the knowledge to do this to you, you likely cannot do anything on the client side so the only option I'd say is that you log or keep a count etc of the number of requests (perhaps to a particular resource) and deny the request (or send a "busy" http code etc) for the particular user.
I think the simplest way would be to count requests from a specific IP address (this obviously has drawbacks such as multiple users behind a proxy or NAT etc).
The actual solution will depend on your server side language and web server but you could perhaps frame up a rule and see how it works. Something like 5 requests per minute (or whatever is appropriate for your usage) per IP address.
正如其他人所说,您必须在服务器上实施保护。再多的客户端编码也无法提供保护。
保护服务器免受此类滥用的常见方法称为
速率限制
。您决定希望给定客户端能够提交消息的频率,并对服务器进行编码以忽略超出该限制的任何消息。例如,您可以决定每分钟允许不超过一条消息,每 10 分钟不超过两条消息,每小时不超过四条消息。您选择任何您认为合理的内容,然后根据该算法进行编码。
在您的服务器中,您必须能够识别消息来自哪个用户(很可能通过身份验证 cookie),并且在您的数据库中,您必须能够找出最后一条消息的发送时间那个用户。您甚至可以将该信息缓存在服务器的 RAM 中(取决于服务器的工作方式),以避免每个请求都进行数据库查找,因为您只需要保留最新信息,并且只需要对重复违规者进行性能优化(那些试图滥用您的服务器并因此最近发送了请求的人)。
As others have said, you have to implement protection on the server. No amount of client-side coding will provide protection.
The common way of protecting a server against this type of abuse is called
rate limiting
. You decide how often you want a given client to be able to submit a message and you code the server to ignore any messages that fall outside that limit.For example, you could decide that you will allow no more than one message a minute and no more than two messages every 10 minutes and no more than four messages an hour. You pick whatever you think seems reasonable and you code to that algorithm.
In your server, you'd have to be able to identify which user the message was coming from (most likely via an authentication cookie) and in your database, you'd have to be able to find out when the last message was sent by that user. You may even be able to cache that information in RAM in your server (depending upon how your server works) to avoid a database lookup on every request since you only have to keep recent info and you only need to performance optimize on the repeat offenders (the ones that are trying to abuse your server and thus just recently sent a request).
我同意每个人都发布的关于速率限制的内容。
然而,这在服务器端实现起来可能非常复杂。尤其是当您开始横向扩展时。而且,老实说,如果 1000 条消息对你造成了那么严重的伤害 - 我的建议可能更适用于你。
您可能不想自己实现此操作,而是希望寻找第三方服务来为您执行此操作,例如这个超酷的 Web 服务代理 Apigee
具体而言,其功能之一是 API 速率限制。 (参见链接)
I agree with what everyone is posting about rate-limiting.
However, this can be very complicated to implement on the server side. Especially when you start scaling out. And, honestly, if 1000 messages hurt you that bad - my suggestion may apply to you even more so.
Instead of implementing this yourself, you may want to look into a third party service to do it for you, such as this super cool web services proxy Apigee
One of their features is, specifically, API rate throttling. (see link)