Forms 如何防止机器人自动填写表单?
我正试图想出一个足够好的反垃圾邮件机制,以防止自动生成的输入。我读过一些技巧,比如验证码,1+1=?这些东西工作得很好,但它们也阻碍了应用程序的免费快速使用(我不想找任何类似的东西) 我尝试在我的所有表单中设置一些隐藏字段,使用Forms 如何防止机器人自动填写表单?,forms,spam,Forms,Spam,我正试图想出一个足够好的反垃圾邮件机制,以防止自动生成的输入。我读过一些技巧,比如验证码,1+1=?这些东西工作得很好,但它们也阻碍了应用程序的免费快速使用(我不想找任何类似的东西) 我尝试在我的所有表单中设置一些隐藏字段,使用display:none 但是,我确信可以将脚本配置为跟踪表单字段id,而不填充它 您是否实施/了解一种良好的反自动表单填充机器人方法?是否有一些东西可以通过HTML和/或服务器端处理无缝完成,并且(几乎)是防弹的?(如果没有JS,您可以简单地禁用它) 我尽量不依赖会话来
display:none代码>
但是,我确信可以将脚本配置为跟踪表单字段id,而不填充它
您是否实施/了解一种良好的反自动表单填充机器人方法?是否有一些东西可以通过HTML和/或服务器端处理无缝完成,并且(几乎)是防弹的?(如果没有JS,您可以简单地禁用它)
我尽量不依赖会话来实现这一点(即计算一个按钮被点击多少次以防止过载)。
reCAPTCHA是一项免费的反机器人服务,帮助图书数字化
谷歌(2009年)已获得:
也看到
- 有关更一般的信息
这些垃圾邮件机器人中的许多只是在网络上徘徊的服务器端脚本。通过在发送表单请求之前使用一些javascript操作表单请求(即,根据一些客户机变量设置附加字段),可以解决其中的许多问题。这不是一个完整的解决方案,可能会导致许多问题(例如,移动设备上没有javascript的用户等),但它可能是攻击计划的一部分
这里有一个简单的例子
<script>
function checkForm()
{
// When a user submits the form, the secretField's value is changed
$('input[name=secretField]').val('goodValueEqualsGoodClient');
return true;
}
</script>
<form id="cheese" onsubmit="checkForm">
<input type="text" name="burger">
<!-- Check that this value isn't the default value in your php script -->
<input type="hidden" name="secretField" value="badValueEqualsBadClient">
<input type="submit">
</form>
函数检查表()
{
//当用户提交表单时,secretField的值将更改
$('input[name=secretField]').val('goodValueEqualsGoodClient');
返回true;
}
在php脚本的某个地方
<?php
if ($_REQUEST['secretField'] != 'goodValueEqualsGoodClient')
{
die('you are a bad client, go away pls.');
}
?>
此外,CAPTCHA很好,而且是抵御垃圾邮件的最佳方法。另一种方法是对可识别对象进行随机图片,而不是像许多网站那样进行随机字母和数字。然后要求用户输入图片中的某个东西是什么颜色,或者该对象本身是什么颜色
总而言之,每种解决方案都有其优缺点。你必须在用户难以通过反垃圾邮件机制和能够通过的垃圾邮件机器人数量之间找到一个令人满意的中间值。机器人无法执行JavaScript,因此你可以使用JavaScript向页面中注入某种隐藏元素,然后在提交表单之前检测到它的存在,但是请注意,因为您的一些用户也将禁用JavaScript
否则,我认为您将被迫使用一种“人性化”的客户证明形式我发现的避免被机器人发送垃圾邮件的最佳解决方案是在您的表单上使用一个非常琐碎的问题或字段
尝试添加如下字段:
- 把盒子里的“你好”抄到一边
- 1+1=
- 复制框中的网站名称
这些技巧要求用户理解表单上必须输入的内容,从而使其更难成为大规模机器人表单填充的目标
编辑
$('#form01 button').click(function(){
//your Validations and if everything is ok:
$('#form01').attr('action', 'correct-action.php').on("load",function(){
document.getElementById('form01').submit()
});
})
正如您在问题中所述,此方法的背面是用户验证其表单的额外步骤。
但是,在我看来,它比验证码简单得多,填写表单时的开销不超过5秒,从用户的角度来看,这似乎是可以接受的。解决反垃圾邮件的一种容易实现但不容易出错(特别是在“特定”攻击上)的方法是跟踪表单提交和页面加载之间的时间
机器人请求页面,解析页面并提交表单。这很快
人类键入URL,加载页面,等待页面完全加载,向下滚动,阅读内容,决定是否评论/填写表单,需要时间填写表单,然后提交
时间上的差异可能很微妙;如何在没有cookies的情况下跟踪这段时间,需要某种方式的服务器端数据库。这可能会影响性能。
您还需要调整阈值时间。一个非常简单的方法是提供一些字段,如
,并放弃所有填写此字段的回复
另一种方法是使用Javascript生成整个表单(或者仅仅是字段名);很少有机器人能运行它
不管怎么说,你不会对来自台湾或印度的实时“机器人”做太多的反对,他们每个发布的链接支付0.03美元,并以此为生。JQuery网站上有一个关于这一点的讨论。尽管它是JQuery,但它的思想是独立于框架的
如果JavaScript不可用,那么您可能需要退回到CAPTCHA类型的方法。我实际上发现一个简单的蜜罐字段可以很好地工作。大多数机器人会填写他们看到的每个表单字段,希望绕过所需的字段验证器
如果您创建一个文本框,将其隐藏在javascript中,然后在服务器上验证该值是否为空,这将淘汰99%的机器人,并且不会给99%的用户带来任何挫折。禁用javascript的剩余1%仍将看到文本框,但您可以为这些情况添加类似“将此字段留空”的消息(如果您关心这些情况的话)
(另外,请注意,如果在字段上设置style=“display:none”,那么机器人很容易看到该字段并丢弃该字段,这就是我喜欢javascript方法的原因)。我发现这样做的简单方法是放置一个带值的字段,并要求用户删除该字段中的文本。因为机器人只会填满它们。如果该字段不为空,则表示该用户不是人类,不会发布。这与验证码的用途相同。我所做的是使用一个隐藏字段,在其上放置时间戳,然后使用PHP将其与服务器上的时间戳进行比较
如果超过15秒(取决于表单的大小),那就是bo
<input type="submit" name="ignore" value="I am a spammer!" />
<input type="image" name="accept" value="submit.png" alt="I am not a spammer" />
<input type="image" name="random125454548" value="random125454548.png"
alt="I perfectly understand that clicking on this link will send the
e-mail to the expected person" />
<input type="image" name="random125452548" value="random125452548.png"
alt="I really want to cancel the submission of this form" />
function formCheck(){
var timeStart;
var timediff;
$("input").bind('click keyup', function () {
timeStart = new Date().getTime();
});
timediff= Math.round((new Date().getTime() - timeStart)/1000);
if(timediff < 3) {
//throw a warning or don't submit the form
}
else submit(); // some submit function
}
<form id="form01" action="false-action.php">
//your inputs
<button>SUBMIT</button>
</form>
$('#form01 button').click(function(){
//your Validations and if everything is ok:
$('#form01').attr('action', 'correct-action.php').on("load",function(){
document.getElementById('form01').submit()
});
})