实用的非图像验证码方法?

317

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

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

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

这种方法的优点是,对于大多数人来说,验证码几乎不会出现!
但是,对于禁用 JavaScript 的用户,我们仍需要一个备选方案,这就是棘手之处。
我已经编写了一个 ASP.NET 传统验证码控件,我们可以重复使用。

CaptchaImage

然而,我更喜欢使用文本方式以避免在每个请求中在服务器上创建所有这些图像的开销。
我看到过一些东西,比如:
ASCII文本验证码:\/\/(_)\/\/ 数学难题:7减去3乘以2等于多少?
问答题:蟾蜍和冰棒哪个更好吃?
也许我只是在做无用功,但如果可能的话,我想要一个资源消耗较小、不基于图像且与<noscript>兼容的CAPTCHA。
有什么好的想法吗?

16
无需在服务器上实际创建图像,只需要处理请求即可。例如:<img src="generateImage.aspx?guid=blah">。 - Brian R. Bondy
58
问答题容易存在文化偏见(想象一下法国人回答你的问题...)。此外,可能遇到英语非母语用户。同时,使用暴力破解很容易就能够破解它们(你只有大约2^#_OfQuestions个选项)。 - Adam Matan
72
还有,什么是冰棒? - Fraser
57
根据 Wolfram Alpha 的计算结果,“what is 7 minus 3 times 2” 等于 1。我原以为答案是 8,现在觉得你刚刚发明了反验证码。 - Mike Robinson
50
我认为程序员在日常使用中应该了解运算符优先级。 - Gnark
显示剩余19条评论
103个回答

4
我会做一个简单的基于时间的CAPTCHA。
启用JavaScript:检查发布时间减去加载时间是否大于HUMANISVERYFASTREADER。
禁用JavaScript:HTTP请求开始时间减去HTTP响应结束时间(存储在会话或隐藏字段中)是否大于HUMANISVERYFASTREADER加上NETWORKLATENCY乘以2。
无论哪种情况,如果返回true,则重定向到图像CAPTCHA。这意味着大多数时候人们不必使用图像CAPTCHA,除非他们是非常快的读者或垃圾邮件机器人设置了延迟响应。
请注意,如果使用隐藏字段,我会为其使用随机ID名称,以防机器人检测到它正在被用作CAPTCHA并尝试修改该值。
另一种完全不同的方法(仅适用于JavaScript)是使用jQuery Sortable函数允许用户对几张图片进行排序。也许是一个小3x3的拼图。

4
如果您结合了一些验证码的想法(任选其中一种或随机选择其中一种):

  • ASCII字符验证码://(_)//
  • 数学题:7减去3乘以2等于多少?
  • 小知识问答:青蛙和冰棒,哪个更好吃?

并且在页面的CSS隐藏部分也放置了完全相同的验证码- 蜜罐想法。这样,您将有一个期望正确答案的地方,另一个地方则应保持答案不变。


1
“什么更好吃”这个问题很主观,我认为。那些对口味有极端看法的人会被视为机器人。此外,只有两个答案的情况下,通过机器人测试的几率是50%。 - pimvdb
在主观方面很正确,但具体情况取决于原始问题。我的观点是随机使用所有三种(或多种)类型。此外,如果答案是多项选择,则通过的机会仅为50%。如果让用户在不列出可能的答案列表的情况下键入单词,则对于机器人来说更难选出问题/答案中的正确单词。 - TheEmirOfGroofunkistan

4
我必须承认,我没有打击垃圾机器人的经验,也不知道它们有多复杂。话虽如此,我在jQuery文章中看不到任何纯粹在服务器上无法实现的内容。
重新表述一下jQuery文章的总结:
1. 在服务器上生成联系表单时... 2. 获取当前时间。 3. 将时间戳与一个秘密词组合,并生成一个32个字符的“哈希”,将其作为cookie存储在访问者的浏览器中。 4. 将哈希或“令牌”时间戳存储在隐藏的表单标记中。 5. 当表单被提交回来时,将时间戳的值与存储在cookie中的32个字符的“令牌”进行比较。 6. 如果信息不匹配、缺失或时间戳过旧,则停止请求的执行...
另一个选择是,如果您想使用传统的图像验证码而不需要在每个请求上生成它们的开销,则可以离线预先生成它们。然后,您只需要随机选择一个来显示每个表单。

3
我认为使用文本验证码的问题在于文本可以被解析,因此可以被回答。如果您的网站很受欢迎(例如Stackoverflow),并且喜欢编码的人经常访问它(例如Stackoverflow),那么有人会将“破解验证码”视为一项易于通过一些简单的JavaScript + Greasemonkey挑战而获胜的挑战。因此,例如,在线程中建议的“隐藏彩色字母方法”(一个很酷的想法),可以通过对以下示例行进行简单解析而轻松破解:
<div id = "captcha">
 <span class = "red">s</span>
 asdasda
 <span class = "red">t</span>
 asdff
 <span class = "red">a</span>
 jeffwerf
 <span class = "red">c</span>
 sdkk
 <span class = "red">k</span>
</div>

同样,解析这个很容易:

3 + 4 = ?

如果遵循模式(x + y)或类似的模式。

同样,如果您有一组问题数组(橙子是什么颜色?有多少个小矮人围绕着白雪公主?),除非您有成千上百个问题,否则可以选择其中30个问题,制作一个问题-答案哈希表,并让脚本机器人重新加载页面,直到找到其中之一。


3
如何使用基于CSS的验证码?
<div style="position:relative;top:0;left:0">
<span style="position:absolute;left:4em;top:0">E</span>
<span style="position:absolute;left:3em;top:0">D</span>
<span style="position:absolute;left:1em;top:0">B</span>
<span style="position:absolute;left:0em;top:0">A</span>
<span style="position:absolute;left:2em;top:0">C</span>
</div>

这将显示"ABCDE"。当然,使用自定义机器人仍然很容易绕过。


3
如果您做一个有不同颜色字母的验证码,并要求用户只输入特定颜色的字母,这样怎么样?

3
如果你不想排除色盲的访问者,那么可供使用的颜色组合相对较少。 - Ken

3

请拨打xxxxx xxxxxxx的电话,让我们谈谈你所在地的天气。

但是现在这些日子过得太快,而且利润导向过于强烈,即使与我们选择的服务提供商进行一次电话交流也对服务提供商来说太昂贵了(时间很宝贵)。

我们大多数时间都接受与机器交流。

悲哀的时代...


3

我一直在使用http://stopforumspam.com作为第一道防线来防御机器人。在我实施它的网站上,它几乎可以不需要使用验证码就能阻止大部分垃圾邮件发送者。


3
一种验证码过滤器的理论想法。向用户提问,服务器可以以某种微不足道的方式回答,用户也可以回答。共享的答案成为一种公钥,由用户和服务器都知道。
一个与Stack Overflow相关的例子: 用户XYZ有多少声望点数? 提示:在屏幕侧面查找此信息,或者跟随此链接。 用户可以随机从已知的Stack Overflow用户中选择。
更通用的例子: 你住在哪里? 周六9:00时你所在地区的天气状况如何? 提示:使用雅虎天气并提供湿度和一般情况。
然后用户输入他们的答案
西雅图 局部多云,湿度85%
计算机确认确实是那个时间在西雅图的天气条件。
答案对用户是唯一的,但服务器有一种方法查找和确认答案。
问题的类型可以各种各样。但是想法是您对人类需要查找的事实和服务器可以轻松查找的事实进行一些处理。该过程是一个双方对话,并需要一定的相互理解。这是一种反转测试。让人类证明它能够提供可计算数据的证据,但是需要人类知识才能产生可计算数据。
另一个可能的实现。你叫什么名字,什么时候出生?
人类将提供已知答案,计算机可以在数据库中查找信息。
也许可以通过机器人填充数据库,但机器人需要具有一定的智能才能组合相关事实。服务器端的数据库或查找表可以被系统地修剪掉明显的垃圾邮件属性。
我相信在实现中还存在缺陷和细节。但是这个概念似乎很可靠。用户提供了一种组合事实,服务器可以查找,但服务器控制应该问的组合类型。组合可以随机化,并且服务器可以使用各种策略来查找共享答案。真正的好处是,您要求用户在其答案中提供一些自我概述和揭示。这使得对于机器人来说更加困难。一堆计算机开始在许多服务器和验证码表单上使用相同的答案,例如
我是1972年下午3:45出生的机器人。
然后,该响应类型可以进行分析并由整个网络用于阻止机器人,有效地使自动化在几次迭代后变得毫无价值。
当我考虑这个问题时,实现基本的阅读理解测试以评论博客文章会很有趣。在博客文章结束后,作者可以向他或她的读者提出问题。问题可以针对每篇博客文章进行唯一设置,并且它具有要求用户在评论之前实际阅读的额外好处。您可以在帖子末尾写下简单的问题,答案存储在服务器端,然后有一系列无意义的问题来加密数据库。
这篇文章谈论了紫色验证码技术吗? 服务器端答案(假,否)

这是一篇关于验证码的文章吗? 服务器端回答(true,是)

这是一篇关于迈克尔·杰克逊的文章吗? 服务器端回答(false,不是)

似乎有几个问题以随机顺序呈现并使顺序具有重要意义是有用的。例如,上面的答案将= no,yes,no。打乱顺序,并混合一些无意义的问题和既有否定答案又有肯定答案的问题。


4
就我个人而言,我不会费心去查找任何天气服务来证明我不是人类,就像我不会费心阅读那些在我能继续前必须要点击广告的网站一样。 - tomjen
也许不是。但这个概念是通用的。在 Stack Overflow 的上下文中,它可以像这样工作。用户 XYZ 有多少声望点?也许您可以在屏幕上提供答案,以节省用户必须执行的步骤。用户将查找答案,系统已经知道答案。用户名可以随机生成。由于数据是实时和动态的,因此很难对机器人进行分析。 - Gordon Potter

3
在我的博客上,如果没有开启 JavaScript,则不接受评论,并通过 Ajax 发布评论。这可以防止所有机器人。我唯一收到的垃圾邮件来自于人类垃圾邮件发送者(他们通常会复制并粘贴网站上的某些文本以生成评论)。
如果必须有非 JavaScript 版本,请执行以下操作:
在以下字符串 [y] 中对 [x] 进行 [某些操作]
给定一个足够复杂的 [x] 和 [y] 且无法使用正则表达式解决,则编写解析器将会很困难。
计算 [dog,dangerous,danceable,cat] 中短单词的数量 = 2
在 [dog,dangerous,danceable,catastrophe] 中哪个单词最短? = dog
在 [fish,mealy,box,stackoverflow] 中以 x 结尾的单词是什么?= box
在 [apple.com, stackoverflow.com, fish oil.com] 中哪个 URL 是非法的?= fish oil.com
所有这些都可以轻松地在服务器端完成;如果选项数量足够大且经常更换,则很难获取所有选项,而且不要让同一用户在同一天内多次获得相同的类型。

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