停止机器人[SO] - PHP

时间:2011-05-08 13:07:35

标签: php security captcha verification

我在index.php中保存了这段代码,填写后点击了“提交”按钮,然后向我显示了验证页面!
我的问题是它是如何检测到它不是来自原始服务器 [我希望他们不使用推荐人,因为它可以轻松禁用]

我的假代码

<html>
 <form id="post-form" action="http://stackoverflow.com/questions/ask/submit" method="post">
  <input id="title" name="title" type="text" maxlength="300" tabindex="100" class="ask-title-field" value="">                        
  <textarea id="wmd-input" name="post-text" cols="92" rows="15" tabindex="101"></textarea>
  <input id="tagnames" name="tagnames" type="text" size="60" value="" tabindex="103">
  <input id="submit-button" type="submit" value="Post Your Question" tabindex="120">  
 </form>
</html>  

任何人都可以指导我创建这样的安全页面 [如果用户尝试从枯燥的页面发帖,他将被要求进行验证]

2 个答案:

答案 0 :(得分:7)

  1. 在服务器上生成令牌。
  2. 将该标记放入隐藏的输入元素中。
  3. 在生成的表单列表中将该令牌保存在服务器上。
  4. 表单提交时
    1. 检查令牌是否已通过且有效,
    2. 从生成的表单列表中删除令牌。
  5. 我怀疑这是问题提交表单中的<input id="fkey" type="hidden" value="..." name="fkey">

答案 1 :(得分:2)

  

好主意,但它也对数据库施加压力:(

您可以创建一个反XSRF令牌,而不必在服务器上记住它们。

您可以通过将要验证的信息放入令牌中来实现此目的,通常包括:

  • 用户ID,因此一个用户无法创建为其他用户提交的表单
  • 到期时间戳,以便令牌永远不会持续

然后将此信息与密钥一起散列并将其吐出隐藏字段。当令牌重新出现时,您可以查看给定的信息,再次使用密钥对其进行哈希处理,并查看哈希是否与用户的提交相匹配。

例如,对于具有到期时间戳1304861680(大约现在的Unix时间)的用户ID 18936,您可以创建一个令牌,如:

18936.1304861680.2A956E39.11E859E44B9308B812257BEE660330D9D0566189

其中2A956E39是一些随机盐,最后一位是使用非常好的密钥18936.1304861680.2A956E39的{​​{1}}的十六进制编码HMAC-SHA1哈希值。

这实现了反XSRF的目的,但有时一次性服务器存储令牌也用于防止表单双重提交。原样,哈希方法对该位没有帮助。但是在创建新实体的特定情况下,这是一个常见的部署双提交预防,您可以将该令牌用作作为新实体的一部分插入到数据库中的唯一值,然后拒绝创建新实体,如果已有一个带有令牌的实体。