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

发布于 2024-10-20 20:48:32 字数 547 浏览 3 评论 0原文

美好的一天,

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

操作的一个示例是:添加/删除“作为我的最爱”的博客文章的按钮。

除非我错了,否则我相信最好的方法是使用 $_SESSION 的变量并避免某人/机器人清除 cookie 来逃避我的保护。我只允许登录用户使用 ajax 函数。

使用数据库会使我的保护变得毫无用处,因为这是我试图避免的不需要的数据库写入。

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

谢谢

编辑:

句子

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

令人困惑,但这与跨域ajax无关。

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

Good day,

I would like to know how to protect my website from ajax-spam. I'm looking to limit any ajax action per
users. Let's say 8 ajax-actions per minute.

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. I'm allowing ajax-functions only to logged-on users.

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.

Thank you

Edit:

The sentense

... to protect my website ...

is confusing but it's not about cross-domain ajax.

Edit 2011-04-20:
I added a bounty of 50 to it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

流星番茄 2024-10-27 20:48:32

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

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

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

Since you're only allowing AJAX actions to logged in users, this is really simple to solve.

  • Create a timestamp field for each account. You can do this in the database, or leverage Memcached, or alternatively use a flat file.
  • Each time the user makes a request through your AJAX interface, add the current timestamp to your records, and:
  • 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.

捶死心动 2024-10-27 20:48:32

您是在谈论针对您网站的特定 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)创建新的哈希值并检查它们是否匹配。

如果表单是由机器人提交的,则不会有 $control_hash,因此不会通过。

Are you talking about specific ajax-spam to your site, or ajax-spam in general?

If the latter, you can use hashes to prevent auto-sending forms, i.e. write your hash() one-way function which takes string and makes sha1-checksum of it.

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. Attach it's value to the ajax-request on form submit. When the form is received by the script, make a new hash from $_REQUEST data (excluding existing $control_hash) and check if they match.

If the form was submitted by bot, it won't have $control_hash, so it won't pass.

旧人 2024-10-27 20:48:32

是的,你的想法原则上是好的。但需要考虑一些事情:

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

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 DoSing your server and preventing legitimate users from being able to use your "Favourite" button.
  • If you track the requests based on their IP then someone could use a bot network (multiple IPs) to get around your blocking. Depending on your site and what your preference is, perhaps limit based on a subnet of the IP.
  • Install and use Memcache to store and track the requests, particularly if you are going to be tracking based on the IP. This should be faster than using session variables (someone might correct me on this).
苯莒 2024-10-27 20:48:32

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

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

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. I.e. 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.

空城仅有旧梦在 2024-10-27 20:48:32

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

目的是否证明手段的合理性?

您还必须判断此类垃圾邮件的概率有多大。大多数机器人都不是很聪明,当涉及到一些日志记录时,它们会惨遭失败。

只是我的 2 美分,其他答案对于避免垃圾邮件来说是完全有效的。

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.

笨笨の傻瓜 2024-10-27 20:48:32

购买更强大的托管服务来满足请求,而不是限制它们。
每分钟 8 个请求,这太荒谬了。
无论如何,如果请求是“合法的”,您应该找到如何处理请求的方法,而不是如何限制它们。如果不“合法”,那么就拒绝它们,没有任何“时间”限制。

Buy more powerful hosting to be able serve requests, don't limit them.
8 requests per minute it's ridiculous.
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.

等数载,海棠开 2024-10-27 20:48:32

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

验证码经过验证后,允许接下来的几篇文章等。

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

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

You can use a session field with a global variable holding the time of last ajax request. Since you want to allow 8 requests, make it an array of size 8 and check for the time differences. 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.

遗心遗梦遗幸福 2024-10-27 20:48:32

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

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文