【问题标题】:How to protect a contact form without captcha?如何在没有验证码的情况下保护联系表格?
【发布时间】:2012-03-01 12:51:22
【问题描述】:

在我的网站上,我有几个表格,某人(无需注册)可以向指定的注册用户发送消息。表格很简单,我想保持这种方式。如果我不想使用任何验证码,保护联系表单免受垃圾邮件和机器人攻击的最佳方法是什么?

Your message:...
Your e-mail:...
[Send]

【问题讨论】:

  • 检查服务器端和客户端的明确验证,并制作邮件功能,不要保存在数据库中
  • 保护什么?如果是垃圾邮件机器人,那么 CAPTCHA 的目的是将机器人与人类区分开来,因此所有机器人保护机制都属于该总称。

标签: php forms


【解决方案1】:

您可以使用 表单密钥 技术保护您的表单:

  1. 当向用户显示表单时,为这个单一的表单提交生成一个随机 ID(“表单密钥”)。将表单密钥存储在会话变量中。在隐藏的输入字段中提交“表单键”。
  2. 在服务器端,检查提交的表单密钥与存储在会话变量中的密钥。使用后立即作废。 (从会话中删除)

如果没有验证码或类似的东西,就不可能真正保护表单免受滥用。

但是,恶意垃圾邮件发送者必须使用这种技术

  1. 通过 HTTP 为每个表单提交请求表单以获得有效的唯一 forkey
  2. 解析DOM树/HTML代码获取表单key
  3. 以正确的格式提交

此技术还可以保护您的表单免受多次意外提交。

这是一个代码示例:

<?php
session_start();
if (isset($_POST['form_submit'])) {
  // do stuff
  if (isset($_POST['formkey']) && isset($_SESSION['formkeys'][$_POST['formkey']])) {
    echo "valid, doing stuff now ... "; flush();
    // delete formkey from session
    unset($_SESSION['formkeys'][$_POST['formkey']]);
    // release session early - after committing the session data is read-only
    session_write_close();
    // do whatever you like with the form data here
    send_contact_mail($_POST);
  }
  else {
    echo "request invalid or timed out.";
  }
}
else {
  // show form with formkey
  $formkey = md5("foo".microtime().rand(1,999999));
  // put current formkey into list of valid form keys for the user session
  if (!is_array($_SESSION['formkeys']) {
    $_SESSION['formkeys'] = array();
  ]
  $_SESSION['formkeys'][$formkey] = now();
?>
<html>
<head><title>form key</title></head>
<body>
  <form method="POST">
    <input type="hidden" name="PHPSESSID" value="<?=session_id()?>">
    <input type="text" name="formkey" 
      value="<?= $formkey ?>">
    <input type="submit" name="form_submit" value="Contact us!">
  </form>
</body>
</html>
<?php } ?>

【讨论】:

  • 谢谢。这是一个很好的解决方案。但是,如果有人打开多个联系表,它将不起作用。用户不应该这样做,所以基本上这是一个很好的解决方案。我会根据你的代码尝试做类似的事情,谢谢你的建议。
  • @Lucas 我修改了我的代码,以便在会话中存储一个有效表单键列表,以便对您的使用案例做出多种形式的反应。此外,这种方法也可以很容易地增强以检查超时。 formkey 现在与时间戳一起存储.. 您唯一需要做的就是插入检查 formkeys 是否已经超时..
  • 您如何实施上述解决方案?
【解决方案2】:

所以选项:

  1. 最大化查询/IP
  2. 添加安全问题
  3. 验证码(即使你不喜欢它)
  4. 发送电子邮件进行验证
  5. 通过 JavaScript 提交数据

关于这些的详细信息以及我对它们的看法。

  1. 它可以很好地防止发送大量消息,但仍然会收到一些消息副本。如果您认为这很实惠,这可能会奏效。注意:垃圾邮件发送者可以使用代理或动态 IP,但这可能会很慢。如果用户发送的电子邮件过多,不妨考虑不阻止用户,而是添加验证码。
  2. 这究竟是什么?这些问题类似于“10+1”或“十加 1”或“今天是几号?”。它们可能运作良好 - 如果您的网站仅使用很少的语言。验证码仍然更好,但以防万一。
  3. 你不喜欢它,但我还是说它是最好的。添加一个 reCAPTCHA 并不难,但它会阻止 90% 的垃圾邮件发送者 - 或更多。但这有两个问题:1. 有时人类也无法阅读它,2. 垃圾邮件发送者可以使用人们以最低限度(如 0.001 美元/验证码)的费用来解决它,有时他们会这样做。但这也代表案例 2。
  4. 可能很好,但如果垃圾邮件发送者注意到这一点,他们可以生成随机电子邮件地址并通过 SMTP 对其进行验证。但他们通常会去最容易的目标并离开。
  5. 很好,垃圾邮件发送者不能让机器人像点击一样,但他们可以制作代码,使点击成为非必需。但最简单的目标规则仍然存在。

在我看来,最好的是解决方案 3,然后是解决方案 2,然后是解决方案 1,然后是解决方案 4 和 5。

【讨论】:

  • 谢谢,这很有用。我想我会首先关注第 4 点,然后是第 1 点。
【解决方案3】:

在我看来,许多网站(售票员、谷歌等主要网站和其他将成为目标的网站除外)可以通过结合使用多种不同的技术来防止没有验证码的评论/垃圾邮件。我最近创建了一个开源 PHP 项目,该项目实现了以下测试以确定提交是否可能是合法的或垃圾邮件。

  • 隐藏表单域 - 如果填写隐藏表单域,则表明垃圾邮件
  • 时间表单提交 - 如果表单填写太快或太慢,这表明垃圾邮件
  • URL 太多 - 如果评论字段的 URL 太多(数量可配置),则表明垃圾邮件
  • 鼠标移动 - 如果用户不使用鼠标,则表示垃圾邮件
  • 使用过的键盘 - 如果用户不使用他们的键盘,这表明垃圾邮件
  • 验证引用者 - 如果 HTTP 引用者与表单 URL 不匹配,我们不应接受提交。
  • 验证电子邮件 - 如果表单中提供的电子邮件地址从语法角度来看无效,我们不应接受提交。

这是项目的 URL。我喜欢上面 Kaii 的测试,它将为 phpFormProtect 做一个很好的额外测试。 https://github.com/mccarthy/phpFormProtect

【讨论】:

  • +1 用于隐藏表单字段和时间表单提交:当我管理一个每天有 50 次垃圾邮件注册的 Drupal 站点时,我尝试了不同的验证码,每个验证码都只产生时间效果;一旦我安装了 HoneyPot(一个实现这两种措施的插件 - 隐藏字段和时间提交)并将隐藏字段名称设置为“电话”,一年多来我收到了 0 个垃圾邮件注册
  • PS 当然这对于小型网站来说是一个很好的措施;如果有人将您的网站定位为垃圾邮件的地方,他们可以轻松处理此问题
  • 同意。正如我在回答中提到的,对于许多网站来说,这已经绰绰有余了。我的目标是平衡用户体验和垃圾邮件/机器人检测。
【解决方案4】:

您可以从 IP 实施时间限制。因此,如果垃圾邮件机器人试图一次又一次地发送表单(在特定的时间间隔内,比如 1 小时),则该请求应该被拒绝。

您必须通过检查和存储用户的 IP 在服务器端执行此操作。然后当他们再次发送表单时,检查用户是否暂时已经在被阻止的 IP 中。

这也是StackOverflow implemented 2 年前的内容。

【讨论】:

    【解决方案5】:

    您可以做一些事情来证明用户是人。如果你想保持简单,也许是一个问数学问题的字段,例如“2 + 5?”。但这并不像验证码那样安全。但是,如果可能的垃圾邮件没有让您感到困扰,那么可以这样做。

    【讨论】:

    • ¿ 为什么不呢?如果以正确的格式提出问题,它可能比克林贡语验证码更清晰
    • @Alfabravo 确切地说,我经常很难阅读 capthcas(是的,我是说你,StackOverflow)。带有错位字母的图像是 2006 年的。
    • 有些脚本可以捕获文本并解决问题,这就是我指出它的原因。
    【解决方案6】:

    使用:iScramble

    它基本上需要一个字符串(您的表单 html 在 PHP 中存储为字符串)并生成一个混淆的 Javascript 块。

    它可以帮助隐藏您用来保护表单的那些表单密钥,或者完全隐藏您的表单以防止机器人被入侵。

    自 90 年代以来我一直在使用它(上面链接中的页面显然至少有那么旧)而且我从来没有收到过垃圾邮件。

    【讨论】:

      猜你喜欢
      • 2013-04-21
      • 2018-09-28
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 2012-09-08
      相关资源
      最近更新 更多