简体   繁体   English

如何防止PHP中的ajax-spam?

[英]How do I protect against ajax-spam in PHP?

Good day, 美好的一天,

I would like to know how to protect my website from ajax-spam. 我想知道如何保护我的网站免受ajax垃圾邮件的侵害。 I'm looking to limit any ajax action per users. 我希望限制每个用户的任何ajax操作。 Let's say 8 ajax-actions per minute. 让我们说每分钟8次ajax动作。

An example of an action would be: a button to add/remove a blog posts "as my favorites". 一个动作的例子是:一个添加/删除博客帖子的按钮“作为我的最爱”。

Unless I'm wrong, I believe the best way would be using $_SESSION 's variable and to avoid someone/a bot to clear cookies to avoid my protection. 除非我错了,否则我认为最好的方法是使用$_SESSION的变量并避免某人/机器人清除cookie以避免我的保护。 I'm allowing ajax-functions only to logged-on users. 我只允许登录用户使用ajax功能。

Using database would make my protection useless because it's the unwanted database's writes I'm trying to avoid. 使用数据库会使我的保护无用,因为这是我想要避免的不需要的数据库写入。

I have to mention that I actually use PHP as server-language and jQuery to proceeds my ajax calls. 我必须提到我实际上使用PHP作为服务器语言和jQuery来进行我的ajax调用。

Thank you 谢谢

Edit: 编辑:

The sentense 感恩

... to protect my website ... ...保护我的网站......

is confusing but it's not about cross-domain ajax. 令人困惑,但它不是关于跨域的ajax。

Edit 2011-04-20: I added a bounty of 50 to it. 编辑2011-04-20:我为它添加了50的赏金。

Since you're only allowing AJAX actions to logged in users, this is really simple to solve. 由于您只允许AJAX操作登录用户,因此解决起来非常简单。

  • Create a timestamp field for each account. 为每个帐户创建一个时间戳字段。 You can do this in the database, or leverage Memcached, or alternatively use a flat file. 您可以在数据库中执行此操作,也可以利用Memcached,或者使用平面文件。
  • Each time the user makes a request through your AJAX interface, add the current timestamp to your records, and: 每次用户通过AJAX界面发出请求时,都会将当前时间戳添加到记录中,并且:
  • Check to make sure the last eight timestamps aren't all before one minute ago. 检查以确保最后八个时间戳不是一分钟前的所有时间戳。

From there you can add additional magic, like tempbanning accounts that flagrantly violate the speed limit, or comparing the IPs of violators against blacklists of known spammers, et cetera. 从那里你可以添加额外的魔法,比如明显违反速度限制的临时账户,或者将违规者的IP与已知垃圾邮件发送者的黑名单等进行比较。

Are you talking about specific ajax-spam to your site, or ajax-spam in general? 您是在谈论特定的ajax垃圾邮件到您的网站,还是ajax垃圾邮件?

If the latter, you can use hashes to prevent auto-sending forms, ie write your hash() one-way function which takes string and makes sha1-checksum of it. 如果是后者,你可以使用哈希来防止自动发送表单,即写你的hash()单向函数,它接受字符串并对其进行sha1校验和。

So that's how you use it: 这就是你如何使用它:

// the page is a blog post #357
$id = 357;
$type = 'post';
$hash = hash($_SERVER['REMOTE_ADDR'].$type.$id);

Put that hash in hidden field which is not within the comment form or even hidden div, somewhere at the bottom of the page, and name it "control_hash" or something. 将该哈希放在隐藏字段中,该字段不在注释表单中,甚至隐藏在页面底部的隐藏div中,并将其命名为“control_hash”或其他内容。 Attach it's value to the ajax-request on form submit. 将它的值附加到表单提交的ajax请求中。 When the form is received by the script, make a new hash from $_REQUEST data (excluding existing $control_hash ) and check if they match. 当脚本收到表单时,从$_REQUEST数据(不包括现有的$control_hash )创建一个新哈希,并检查它们是否匹配。

If the form was submitted by bot, it won't have $control_hash , so it won't pass. 如果表单是由bot提交的,它将没有$control_hash ,因此它不会通过。

Yes, your idea in principle is good. 是的,你的理念原则上是好的。 Some things to consider though: 有些事情需要考虑:

  • If you track the limits globally then you may run into the issue of a bot DoS ing your server and preventing legitimate users from being able to use your "Favourite" button. 如果您追踪全球范围的限制,那么你可能会遇到一个bot的问题的DoS荷兰国际集团服务器和防止合法用户不能够使用你的“收藏”按钮。
  • If you track the requests based on their IP then someone could use a bot network (multiple IPs) to get around your blocking. 如果您根据他们的IP跟踪请求,那么有人可以使用僵尸网络(多个IP)来绕过您的阻止。 Depending on your site and what your preference is, perhaps limit based on a subnet of the IP . 根据您的站点和您的偏好,可能会根据IP子网进行限制。
  • Install and use Memcache to store and track the requests, particularly if you are going to be tracking based on the IP. 安装并使用Memcache来存储和跟踪请求,特别是如果您要基于IP进行跟踪。 This should be faster than using session variables (someone might correct me on this). 这应该比使用会话变量更快(有人可能会纠正我)。

If you have access to the source code of the web-site, you can rewrite some of the javascript code that actually performs AJAX-request. 如果您可以访问网站的源代码,则可以重写一些实际执行AJAX请求的javascript代码。 Ie your pages can have a hidden counter field, that is incremented every time a user clicks the button. 即您的页面可以有一个隐藏的计数器字段,每次用户单击该按钮时都会递增。 And also you can have a timefield hidden on the page, in order to rate the frequency of clicks. 此外,您还可以在页面上隐藏时间字段,以便对点击次数进行评级。

The idea is that you don't even have to send anything to the server at all - just check it on the client side inside the script. 这个想法是你根本不需要向服务器发送任何东西 - 只需在脚本内的客户端进行检查。 Of course, that will not help against the bots adressing directly to the server. 当然,这无法帮助机器人直接对服务器进行攻击。

It really depends on the result of such a spam. 这真的取决于这种垃圾邮件的结果。 If you just want to avoid writing to your database, all these check could end up taking more ressources than actually writing to the database. 如果您只是想避免写入数据库,那么所有这些检查最终可能会占用比实际写入数据库更多的资源。

Does the end justify the means? 最终证明手段合理吗?

You also have to judge what's the probability of such a spam. 您还必须判断此类垃圾邮件的概率是多少。 Most bots are not very smart and will miserably fail when there's some logging involved. 大多数机器人都不是很聪明,并且当涉及到一些日志记录时会很糟糕。

Just my 2 cents, the other answers are perfectly valid to avoid spam. 只需2美分,其他答案完全有效,可以避免垃圾邮件。

Buy more powerful hosting to be able serve requests, don't limit them. 购买更强大的托管服务请求,不要限制它们。 8 requests per minute it's ridiculous. 每分钟8个请求很荒谬。
Anyway, if requests are 'legal', you should find ways how to serve requests, not how to limit them. 无论如何,如果请求是“合法的”,您应该找到如何处理请求的方法,而不是如何限制请求。 And if not 'legal' - then deny them without any 'time' limitations. 如果不是“合法的” - 然后在没有任何“时间”限制的情况下否认它们。

You can use a session field with a global variable holding the time of last ajax request. 您可以使用具有全局变量的会话字段,该变量保存上次ajax请求的时间。 Since you want to allow 8 requests, make it an array of size 8 and check for the time differences. 由于您要允许8个请求,因此请将其设置为大小为8的数组,并检查时间差异。 If it increases, (important) it might not always be a bot. 如果它增加,(重要)它可能并不总是机器人。 give the user a chance with captcha or something similar. 为用户提供验证码或类似的机会。 (a math problem maybe?) (也许是数学问题?)

once the captcha is validated, allow the next few posts etc.. 验证验证码后,允许接下来的几个帖子等。

But do make sure that you are checking for that particular session and user. 但请确保您正在检查该特定会话和用户。

Kerin's answer is good, I just wanted to emphasize on captcha. Kerin的答案很好,我只是想强调验证码。

yes you need to use a function in every function views can interact, also, it should be in global library so you can use it anywhere. 是的,你需要在每个函数视图中使用一个函数进行交互,它也应该在全局库中,这样你就可以在任何地方使用它。

if(is_logged_in())
{
    // do you code here 
}

while is_logged in is defined as follows 而is_logged in定义如下

function is_logged_in($activated = TRUE)
{
    return $this->ci->session->userdata('status') === ($activated ? STATUS_ACTIVATED : STATUS_NOT_ACTIVATED);
}

you should set the status session when user login successfully. 您应该在用户成功登录时设置状态会话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM