今天看到这篇文章:Safer Contact Forms Without CAPTCHA’s,仔细想了下,得出的结论是,如果你的网站对于机器人来说没有什么太大的利用价值,那么这种验证方式已经足够了,如果垃圾信息发送者认为你的网站很有价值,那么破解起来也很方便。

1、先说原理
  我们使用图形验证码(当然还有声音等其他方式),主要就是欺负机器人看不懂复杂的图片。上面这篇文章中提到的方法就是将验证信息隐藏在用Ajax生成的表单隐藏域中,说白了,也就是欺负机器人看不懂JS生成的隐藏域和cookie。其实这只是个掩耳盗铃的做法。我们来看一下原文代码:

$ct mktime();
setcookie('token',md5('secret salt'.$ct), 0'/');
# 'Expires' in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

# Always modified
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");

# HTTP/1.1
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0"false);

# HTTP/1.0
header("Pragma: no-cache");
echo 
$ct

  首先给浏览器一个加密的cookie值,然后给表单一个时间戳,验证时对比下cookie和时间戳的编码规则是否匹配。如果机器人要破解,有这么个办法:首先人工获取cookie和时间戳,然后伪造这个cookie,让机器人同时发送到评论入口就行了。

2、解决办法
  Cookie可以伪造,但是相比之下伪造session就要难的多,因为session的生成是服务器和客户端同时进行的,所以选用session来生成这个验证串要保险的多。另外就是诸如WP之类的Blog程序,针对每篇日志增加一个特定的日志编号+时间戳+密钥的编码串,阻止机器人的目的也就达到了,因为在合理的时间范围内垃圾信息发送者不可能再去获取一个特定的匹配密钥然后设定给机器人,这划不来,还不如手工发垃圾呢。