看起来我们将为Stack Overflow添加CAPTCHA支持。这对于防止机器人、垃圾邮件发送者和其他恶意脚本活动是必要的。我们只希望人类在这里发布或编辑东西!

我们将使用JavaScript (jQuery)验证码作为第一道防线:

http://docs.jquery.com/Tutorials:Safer_Contact_Forms_Without_CAPTCHAs

这种方法的优点是,对于大多数人来说,CAPTCHA永远不会可见!

然而,对于禁用JavaScript的人,我们仍然需要一个备用方案,这就是棘手的地方。

我为ASP编写了一个传统的CAPTCHA控件。NET,我们可以重复使用。

但是,我更倾向于使用一些文本化的东西,以避免为每个请求在服务器上创建所有这些图像的开销。

我见过这样的事情…

ASCII文本验证码:\/\/(_)\/\/ 数学难题:7减3乘以2等于多少? 小问题:癞蛤蟆和冰棍,哪个更好吃?

也许我只是在风车这里倾斜,但我希望有一个更少的资源密集型,非图像为基础的<noscript>兼容的验证码,如果可能的话。

想法吗?


当前回答

非常简单的算术很好。盲人也能回答。(但正如Jarod所说,要注意操作符优先级。)我想有人可以编写一个解析器,但这使得垃圾邮件的成本更高。

足够简单,并且围绕它编写代码并不困难。我看到了两个威胁:

随机的垃圾邮件机器人和可能支持它们的人类垃圾邮件机器人;而且 机器人创建游戏堆栈溢出

通过简单的算术,你可以打败威胁1,但不能打败威胁2。

其他回答

我确信大多数页面都是使用支持鼠标悬停的控件(按钮、链接等)构建的。

不是显示图像并要求用户输入内容,而是要求用户将鼠标移动到任意控件(以随机顺序选择控件(任何按钮或链接))。 并将颜色应用到控件(一些随机的颜色)上鼠标(小JavaScript做的伎俩).. 然后让用户在鼠标上输入他/她所看到的颜色。

这只是一种不同的方法,我并没有实现这个方法。但这是可能的。

使用简单的文本验证码,然后要求用户倒着输入答案,或者只输入第一个字母,或者最后一个字母,或者其他随机的东西。

另一个想法是制作一个ASCII图像,像这样(来自《传送门》游戏结束序列):

                             .,---.
                           ,/XM#MMMX;,
                         -%##########M%,
                        -@######%  $###@=
         .,--,         -H#######$   $###M:
      ,;$M###MMX;     .;##########$;HM###X=
    ,/@##########H=      ;################+
   -+#############M/,      %##############+
   %M###############=      /##############:
   H################      .M#############;.
   @###############M      ,@###########M:.
   X################,      -$=X#######@:
   /@##################%-     +######$-
   .;##################X     .X#####+,
    .;H################/     -X####+.
      ,;X##############,       .MM/
         ,:+$H@M#######M#$-    .$$=
              .,-=;+$@###X:    ;/=.
                     .,/X$;   .::,
                         .,    ..  

并给用户一些选项,如:IS A, LIE, BROKEN HEART, CAKE。

有人还建议使用Raphael JavaScript库,它显然可以让你在所有流行的浏览器的客户端上作画:

http://dmitry.baranovskiy.com/raphael/

.. 但这并不完全适用于我的<noscript>情况,不是吗?:)

验证码检查你是人还是电脑。 问题是,在那之后,计算机需要判断你是否是人类。

因此,一个解决方案是让一个用户填写CAPTCHA,让下一个用户检查它。 问题当然是时间差距。

我开发的一个方法,似乎工作得很完美(虽然我可能不会像你一样收到那么多评论垃圾邮件),是有一个隐藏字段,并填充一个虚假的值,例如:

<input type="hidden" name="antispam" value="lalalala" />

然后,我有一段JavaScript,它每秒更新的值与页面已加载的秒数:

var antiSpam = function() {
        if (document.getElementById("antiSpam")) {
                a = document.getElementById("antiSpam");
                if (isNaN(a.value) == true) {
                        a.value = 0;
                } else {
                        a.value = parseInt(a.value) + 1;
                }
        }
        setTimeout("antiSpam()", 1000);
}

antiSpam();

然后当表单提交时,如果反垃圾邮件值仍然是“lalalala”,那么我将其标记为垃圾邮件。如果反垃圾邮件值是整数,我会检查它是否大于10(秒)。如果低于10,我把它标记为垃圾邮件,如果超过10,我就让它通过。

If AntiSpam = A Integer
    If AntiSpam >= 10
        Comment = Approved
    Else
        Comment = Spam
Else
    Comment = Spam

理论是:

垃圾邮件机器人不支持JavaScript,只提交它看到的内容 如果机器人支持JavaScript,它会立即提交表单 评论者在发帖前至少阅读了一些页面内容

这种方法的缺点是它需要JavaScript,如果您没有启用JavaScript,您的评论将被标记为垃圾邮件,但是,我确实会查看标记为垃圾邮件的评论,所以这不是问题。

回应评论

@MrAnalogy:服务器端方法听起来是一个很好的想法,和在JavaScript中完全一样。良好的电话。

@AviD:我知道这种方法很容易受到直接攻击,就像我在博客上提到的那样。然而,它将防御你的平均垃圾邮件机器人盲目提交垃圾的任何形式,它可以找到。