如何在PHP中防止ajax垃圾邮件?

6

您好,

我想了解如何保护我的网站免受ajax-spam的侵害。我希望限制每个用户的任何ajax操作次数。比如,每分钟只能进行8个ajax操作。

一个操作的例子是:一个按钮可以将博客文章“添加/移除为我的收藏”。

除非我错了,我认为最好的方法是使用 $_SESSION 变量,并避免某人/机器人清除cookie以避免我的保护措施。我仅允许已登录的用户使用ajax函数。

使用数据库将使我的保护失效,因为我要避免的是不必要的数据库写入。

我必须提到,我实际上使用 PHP 作为服务器语言, jQuery 来处理我的ajax调用。

谢谢

编辑:

句子

... 保护我的网站...

很困惑,但与跨域ajax无关。

编辑2011-04-20: 我为此设定了50美元的赏金。


我的猜测是这是某种 API。如果不是的话,我会同意你的看法,除非有理由(比如它是一个游戏)。但如果是游戏的话,我会使用某种数据库跟踪来防止后门。 - Kevin Peno
@Tsadiq,假设我有一个类似于这个页面的页面,并且我想阻止用户对“收藏”按钮(开/关)进行垃圾邮件攻击。 - Cybrix
@Cybrix,会话变量会使问题稍微复杂一些,是的。你之前说过cookie,所以我就基于那个假设在运行。那么我的下一个问题是,你怎么知道会话不是新的,而是有人删除了会话cookie? - Kevin Peno
另外,值得注意的是,如果您发布您要完成的详细目标而不是正在做的事情,这可能会更有帮助。这将有助于人们理解您的解决方案,找到其中的漏洞,并提出建议。以现在的情况来看,我认为您不会获得有价值的答案。 - Kevin Peno
@kjy112,不是的。同一域名垃圾邮件。我正在尝试找到一种方法来防止用户进行ajax垃圾邮件。 - Cybrix
显示剩余9条评论
8个回答

9

由于您只允许已登录的用户进行AJAX操作,因此解决这个问题非常简单。

  • 为每个账户创建一个时间戳字段。您可以在数据库中执行此操作,也可以利用Memcached,或者使用平面文件。
  • 每次用户通过您的AJAX接口发出请求时,将当前时间戳添加到您的记录中,并:
  • 检查最近的八个时间戳是否都在一分钟之前之前。

从那里,您可以添加其他魔法,例如临时禁止违反速度限制的帐户,或将违规者的IP地址与已知垃圾邮件发送者的黑名单进行比较等等。


+1个好解决方案。让我们等一下看看其他解决方案,但我怀疑不会有太大的区别。 - Cybrix
@Cybrix,没问题。另外,如果你发现有很多恶意的AJAX请求被账户限制模型捕获,那么最好确保登录检查逻辑不涉及复杂的数据库查询,如连接或总共超过几个查询。将太多的数据库开销暴露给像会话检查这样容易受到攻击的进程会使你容易受到DDoS攻击的威胁。 - Winfield Trail

1

你是在谈论针对你的网站的特定ajax垃圾邮件,还是一般的ajax垃圾邮件?

如果是后者,您可以使用哈希来防止自动发送表单,即编写一个hash()单向函数,它接受字符串并对其进行sha1校验和。

这就是如何使用它:

// 该页面是博客文章#357
$id = 357;
$type = 'post';
$hash = hash($_SERVER['REMOTE_ADDR'].$type.$id);

将该哈希放入隐藏字段中,该字段不在评论表单内,甚至不在隐藏的div中,而是在页面底部的某个地方,并将其命名为“control_hash”或其他名称。在表单提交时将其值附加到ajax请求上。当脚本接收到表单时,从$_REQUEST数据(不包括现有的$control_hash)生成新哈希,并检查它们是否匹配。

如果表单是由机器人提交的,则它将没有$control_hash,因此无法通过。


如果表单是由机器人提交的,它将没有$control_hash,因此无法通过。
这是基于机器人是通用的,并不针对特定网站进行定制的假设。这个假设是不安全的。
- Winfield Trail
1
@Kerin “当你做出假设时,你会让你和我都变得很蠢。” - ᴍᴇʜᴏᴠ
是的,那差不多就是我说的。另外,我不知道如何取消点赞你的评论,那是一个意外。 - Winfield Trail
你的哈希检查没有解决任何问题,也没有增加除他最初要求的基于时间限制以外的安全性。 - Winfield Trail
@Kerin “没有偶然。”我提到我在谈论普遍的机器人。如果您运行的网站可能成为专门定制机器人的目标,当然您应该使用比仅哈希检查更复杂的安全方法,这是要在此网站上询问的主题。 - ᴍᴇʜᴏᴠ

0

是的,你需要在每个函数中使用一个函数来实现视图之间的交互,而且它应该在全局库中,这样你就可以在任何地方使用它。

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

当is_logged in定义如下时

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

用户成功登录后,您应该设置状态会话。


它将如何帮助防止垃圾邮件,伙计?因为用户可以登录,然后将cookie传递给垃圾邮件脚本。 - Steel Brain

0

如果您可以访问网站的源代码,您可以重写一些实际执行 AJAX 请求的 JavaScript 代码。例如,您的页面可以有一个隐藏的计数器字段,每次用户点击按钮时都会增加。此外,您还可以在页面上隐藏一个时间字段,以评估点击频率。

这个想法是您甚至不必向服务器发送任何内容 - 只需在脚本内部在客户端上检查即可。当然,这对于直接寻址服务器的机器人是无济于事的。


0

这真的取决于这种垃圾邮件的结果。如果你只是想避免写入数据库,所有这些检查可能会消耗比实际写入数据库更多的资源。

目的是否正当?

您还必须判断此类垃圾邮件的概率。大多数机器人并不聪明,在涉及某些日志记录时将失败。

这只是我的个人意见,其他答案完全有效以避免垃圾邮件。


0
购买更强大的托管服务以能够处理请求,不要限制它们。每分钟8个请求是荒谬的。
无论如何,如果请求是“合法”的,您应该找到方法来处理请求,而不是限制它们。如果不“合法”,则应该在没有任何“时间”限制的情况下拒绝它们。

0

你可以使用一个会话字段,并使用一个全局变量保存上次ajax请求的时间。因为你想允许8个请求,所以将其定义为一个大小为8的数组,并检查时间差异。如果时间增加了(很重要),不一定是机器人,可以给用户一个验证码或类似的东西(比如一个数学问题)来确认。

一旦验证码验证通过,就允许下一批帖子等等。

但请确保你在检查特定的会话和用户。

Kerin的回答很好,我只是想强调一下验证码的重要性。


0

是的,你的想法原则上是好的。但需要考虑以下几点:

  • 如果你全局跟踪限制,那么你可能会遇到机器人 DoS 你的服务器并阻止合法用户使用你的“收藏”按钮的问题。
  • 如果你基于IP跟踪请求,那么有人可以使用机器人网络(多个IP)来绕过你的阻止。根据你的网站和你的偏好,也许应该基于IP子网进行限制。
  • 安装和使用Memcache来存储和跟踪请求,特别是如果你要基于IP跟踪。这应该比使用会话变量更快(也许有人会纠正我)。

问:对于像这样的东西,Memcache相比APC有什么好处吗?(如果有的话) - Kevin Peno
我不知道具体情况,但我建议使用Memcache纯粹是为了将值存储在内存中,而不是写入会话文件。据我所知,APC也可以做类似的事情,所以可以选择任何一种。 - Blair McMillan
我认为限制Ajax最有效的方法是按用户,而不是按函数来限制。 - Cybrix
谢谢回复。我只是好奇为什么在这种情况下您选择了这个扩展名。我想这类似于我喜欢Windex胜过Target品牌。 - Kevin Peno
@Kevin,哈哈。就是那样。 - Blair McMillan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接