繁体   English   中英

如何防止PHP中的ajax-spam?

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

美好的一天,

我想知道如何保护我的网站免受ajax垃圾邮件的侵害。 我希望限制每个用户的任何ajax操作。 让我们说每分钟8次ajax动作。

一个动作的例子是:一个添加/删除博客帖子的按钮“作为我的最爱”。

除非我错了,否则我认为最好的方法是使用$_SESSION的变量并避免某人/机器人清除cookie以避免我的保护。 我只允许登录用户使用ajax功能。

使用数据库会使我的保护无用,因为这是我想要避免的不需要的数据库写入。

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

谢谢

编辑:

感恩

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

令人困惑,但它不是关于跨域的ajax。

编辑2011-04-20:我为它添加了50的赏金。

由于您只允许AJAX操作登录用户,因此解决起来非常简单。

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

从那里你可以添加额外的魔法,比如明显违反速度限制的临时账户,或者将违规者的IP与已知垃圾邮件发送者的黑名单等进行比较。

您是在谈论特定的ajax垃圾邮件到您的网站,还是ajax垃圾邮件?

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

这就是你如何使用它:

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

将该哈希放在隐藏字段中,该字段不在注释表单中,甚至隐藏在页面底部的隐藏div中,并将其命名为“control_hash”或其他内容。 将它的值附加到表单提交的ajax请求中。 当脚本收到表单时,从$_REQUEST数据(不包括现有的$control_hash )创建一个新哈希,并检查它们是否匹配。

如果表单是由bot提交的,它将没有$control_hash ,因此它不会通过。

是的,你的理念原则上是好的。 有些事情需要考虑:

  • 如果您追踪全球范围的限制,那么你可能会遇到一个bot的问题的DoS荷兰国际集团服务器和防止合法用户不能够使用你的“收藏”按钮。
  • 如果您根据他们的IP跟踪请求,那么有人可以使用僵尸网络(多个IP)来绕过您的阻止。 根据您的站点和您的偏好,可能会根据IP子网进行限制。
  • 安装并使用Memcache来存储和跟踪请求,特别是如果您要基于IP进行跟踪。 这应该比使用会话变量更快(有人可能会纠正我)。

如果您可以访问网站的源代码,则可以重写一些实际执行AJAX请求的javascript代码。 即您的页面可以有一个隐藏的计数器字段,每次用户单击该按钮时都会递增。 此外,您还可以在页面上隐藏时间字段,以便对点击次数进行评级。

这个想法是你根本不需要向服务器发送任何东西 - 只需在脚本内的客户端进行检查。 当然,这无法帮助机器人直接对服务器进行攻击。

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

最终证明手段合理吗?

您还必须判断此类垃圾邮件的概率是多少。 大多数机器人都不是很聪明,并且当涉及到一些日志记录时会很糟糕。

只需2美分,其他答案完全有效,可以避免垃圾邮件。

购买更强大的托管服务请求,不要限制它们。 每分钟8个请求很荒谬。
无论如何,如果请求是“合法的”,您应该找到如何处理请求的方法,而不是如何限制请求。 如果不是“合法的” - 然后在没有任何“时间”限制的情况下否认它们。

您可以使用具有全局变量的会话字段,该变量保存上次ajax请求的时间。 由于您要允许8个请求,因此请将其设置为大小为8的数组,并检查时间差异。 如果它增加,(重要)它可能并不总是机器人。 为用户提供验证码或类似的机会。 (也许是数学问题?)

验证验证码后,允许接下来的几个帖子等。

但请确保您正在检查该特定会话和用户。

Kerin的答案很好,我只是想强调验证码。

是的,你需要在每个函数视图中使用一个函数进行交互,它也应该在全局库中,这样你就可以在任何地方使用它。

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);
}

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

暂无
暂无

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

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