停止欺骗性表单提交
我有一个关于停止欺骗性表单提交的问题。如果使用 $_SERVER['HTTP_REFERER']
我只允许从我的网站提交表单,怎么样?那会有帮助吗?谢谢!
I have a question about stopping spoofed form submissions. How about if by using the $_SERVER['HTTP_REFERER']
I only allow submissions to my forms coming from my website? Would that help?! Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
这会有所帮助,并且添加起来相当容易,但它不会阻止有针对性的攻击,毕竟您可以欺骗
HTTP_REFERER
标头。需要记住的一件事是客户端不需要发送
HTTP_REFERER
,因此如果标头丢失,您可能仍然希望允许提交。如果这是不可能的,那么检查HTTP_REFERER
对您没有帮助。搜索验证码“完全自动化的公共图灵测试来区分计算机和人类”,这就是您真正要找的。
It would help, and it's fairly easy thing to add but it wont stop a targeted attack, after all you can spoof a
HTTP_REFERER
header.One thing to keep in mind is that a client is not required to send a
HTTP_REFERER
, so if the header is missing you might want to allow submissions anyway. If this is not possible, then checkingHTTP_REFERER
wont help you.Run a search for CAPTCHA "Completely Automated Public Turing test to tell Computers and Humans Apart", this is what you're really looking for.
让我们明确一点:从技术上来说,阻止欺骗性表单提交是不可能的。用一句话概括就是:
Let us be clear: it's technically impossible to prevent spoofed form submissions. Summing it up in one sentence:
表单欺骗的主要问题是您无法控制客户端发送的内容。用户可以更改任何表单参数。因此,客户端在表单提交时发送的所有内容都需要进行验证和验证。
这也意味着,您提供的在表单中发送的参数越少,您需要验证和验证的参数就越少。特别是预设的且不由用户更改的参数(即隐藏表单字段)如果不是真正必要,则不需要嵌入到表单中。相反,您可以将它们存储在会话中的容器中,并且仅通过隐藏字段引用该容器。如果这不是一个选项,请确保您至少可以通过使用 MAC。
另一个问题是,成功提交表单所需发送的表单参数是完全可预测的,因此攻击者可以重复发送有效的表单提交。如果您需要一个不可预测的参数,该参数只能由您的服务器发出并在表单提交时进行验证,您可以验证表单提交是否已被授予。
一种解决方案是使用根据表单请求生成的随机一次性令牌,该令牌存储在会话中以及作为隐藏输入字段放入表单中。然后在提交表单时检查是否提供了令牌以及它是否等于会话中存储的令牌;如果它们相等,则您从会话中删除令牌并处理表单,否则您拒绝表单处理。
坦率地说,这种机制并不完美,因为您仍然可以先请求表单,然后发送欺骗性的表单数据。您可以在此处使用额外的验证码或其他阻止自动请求的机制。
最好的方法是结合使用上述所有措施:
此外,这些基于会话的表单容器还可以防止 CSRF 因为攻击第三方无法预测其标识符。
The main issues with form spoofing is that you don’t have any control over what the client sends. The user could change any form parameter. So everything the client sends on form submission needs to be validated and verified.
This also means, the less parameters you provide to be send in the form, the less you need to validate and verify. Particularly parameters that are preset and not to be changed by the user (i. e. hidden form fields) don’t need to be embedded into the form if not really necessary. Instead you could store them in a container in the session and only refer to this container via a hidden field. If this is not an option, make sure that you at least can detect any integrity flaw by singing the preset values with a MAC.
Another issue is that the form parameters that need to be send for a successful form submission are quite predictable so that an attacker could send repeatedly valid form submissions. If you would require a non-predictable parameter that can only be issued by your server and is validated on form submission, you could verify that the form submission is granted.
One solution would be to use a random one-time token that is generated on form request and is stored in the session as well as put into the form as a hidden input field. Then on form submission you check if a token was provided and whether it is equal to the one stored in the session; if they are equal, the you remove the token from the session and process the form, otherwise you deny the form processing.
Frankly, this mechanism is not perfect as you could still request the form first and then send a spoofed form data. That’s where you could use additional Captchas or other mechanisms that prevent automatic requests.
The best would be to use a combination of all measures mentioned above:
Additionally, these session based form containers do also prevent CSRF as their identifiers are unpredictable for an attacking third party.
停止?没有,有限制吗?可能吧。您的网站是否真的受到了数量惊人的欺骗性表单提交的攻击,或者您只是先发制人?不要解决不存在的问题。
Stop? No. Limit? Possibly. Is your website really being hit with an alarming number of spoofed form submissions, or are you just being preemptive? Don't solve problems that aren't there.
推荐人很容易被欺骗。
您应该尽可能地验证表单以发现愚蠢的机器人,并可能使用服务器端验证码。
The referrer is easily spoofed.
You should validate the form best you can to catch out stupid bots, and possibly use a server side CAPTCHA.
Referer 很容易被欺骗,因此任何想要欺骗表单提交的攻击者也可以欺骗 Referer 标头。另外,我不认为网络浏览器需要发送 Referer 标头,因此它可能会排除合法用户的表单帖子。
Referer is easy to spoof, so any attacker that wanted to spoof a form submission could just spoof the Referer header as well. Also, I don't believe web browsers are required to send the Referer header, so it could potentially exclude form posts from legitimate users.
尝试使用 ReCaptcha 等验证码。您不仅可以防止垃圾邮件机器人向您的网站发送垃圾邮件,而且您还可以仅“授权”那些使用您表单的人(至少在某种程度上 - 他们需要加载您的表单才能获取验证码,然后发送回复)。
Try a captcha like ReCaptcha. Not only you will prevent spambots from spamming your website but you'll also be able to "authorise" only those people who use your form (at least to some extent - they will need to load your form to get the captcha and then send a response).
欺骗 HTTP 标头非常容易,因此不应该用于需要严格安全性的情况。通常使用的一种技术是在表单上的隐藏输入中发送加密的 cookie 和匹配的加密令牌。该 cookie 应该是仅 HTTP 的 cookie。提交表单时,检查 cookie 中的值和隐藏输入中的值是否匹配。这将有助于防止跨站点请求伪造,因为其他站点无法成功向您的站点发出请求,因为它们要么会丢失 cookie(对于 MIM 攻击),要么会丢失隐藏输入(欺骗表单)。当然,这取决于您确保您的网站在其他方面是安全的,这样他们就无法嗅探令牌来找出要提供的内容。
这里有一个关于如何在 ASP.NET MVC 中完成此操作的精彩讨论,http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
Spoofing HTTP headers is pretty easy and so shouldn't be used for something that requires rigorous security. One technique typically used is to send both an encrypted cookie and a matching, encrypted token in a hidden input on the form. The cookie should be an HTTP-only cookie. On form submission check that the value from the cookie and the value from the hidden input match. This will help prevent cross-site request forgeries since a request to your site can't be successfully made from another site because they'll either be missing the cookie (for a MIM attack) or the hidden input (spoofed form). Of course, this depends on you making sure your site is otherwise secure so they can't sniff the tokens to find out what to supply.
Here's a nice discussion on how this is done in ASP.NET MVC, http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
如果没有“欺骗”的定义,那就只是一句空话。
有十几种不同的“恶搞”,每种都有不同的保护。
最通用的解决方案是验证码。
Without definition of "spoofing" it would be but empty talk.
There are a dozen of different "spoofs", each with it's different protection.
Most general solution is CAPTCHA.
一个建议是使用令牌。如果您使用任何流行的 MVC 架构,则无需担心,因为已经做好了欺骗预防工作。但如果您像我一样采用自定义 MVC 架构,那么令牌就是一种方法。在您的数据库类中,对于每个 CRUD(CREATE、READ、UPDATE AND DELETE) 函数,检查令牌。例如
可以通过 md5 生成令牌。
或者,您可以轻松地将您的 Web 应用程序与此跨站点请求伪造保护套件集成。请查看此处
A suggestion would be to use a token. If you are using any of the popular MVC architectures, you do not need to worry as spoofing prevention is taken care of. But if you are on a custom MVC Architecture like myself, a token is an approach. In your Database class, for every CRUD(CREATE, READ, UPDATE AND DELETE) function, check for the token. e.g
the token can be generated via md5.
Alternatively, you can easily integrate your web application with this Cross-Site Request Forgery protection kit. Check it out here
真的没有帮助。读这个:
http://shiflett.org/articles/form-spoofing
Doesn't really help. Read this:
http://shiflett.org/articles/form-spoofing