我网站上的用户有一个公开可见的个人资料,他们通过一个简单的 HTML 表单接受订阅。这些订阅将合并到该用户的电子邮件列表中。
有人可以编写一个脚本来不断地注册电子邮件以破坏/淹没用户的列表。这可以通过使用基于 IP 的速率限制来缓解,但如果脚本在分布式环境中运行,此解决方案将不起作用。
我能想到的唯一策略是使用验证码,但我真的很想避免这样做。我还能尝试什么?
我网站上的用户有一个公开可见的个人资料,他们通过一个简单的 HTML 表单接受订阅。这些订阅将合并到该用户的电子邮件列表中。
有人可以编写一个脚本来不断地注册电子邮件以破坏/淹没用户的列表。这可以通过使用基于 IP 的速率限制来缓解,但如果脚本在分布式环境中运行,此解决方案将不起作用。
我能想到的唯一策略是使用验证码,但我真的很想避免这样做。我还能尝试什么?
您的问题基本上归结为“如何在不使用 CAPTCHA 的情况下区分人类和计算机?”
这确实是一个相当复杂的问题,有很多不同的答案和方法。在下文中,我将尝试列举一些。一些想法取自这篇文章(德语)。
我个人认为某种验证码将是一个完美的解决方案。这不一定是图像中的扭曲文本,您也可以使用逻辑谜题或简单的计算。但是通过以下方法,您可以尝试避免验证码;请记住,这些方法总是比需要用户交互的 CAPTCHA 更容易绕过。
在表单中使用隐藏字段作为蜜罐(type=hidden
或者使用 CSS)。如果此字段已填写(或具有超出您预期的其他值),则您已检测到一个机器人(垃圾邮件机器人通常不执行语义分析,因此它们会填写它们找到的所有内容)。但是,如果机器人专门针对您,或者只是了解字段的名称并避免它,这将无法正常工作。
使用 JavaScript 检查表单提交的速度。当然,人类需要一些时间(至少几秒钟)来填写表格,而机器人要快得多。您还应该检查表单是否在短时间内多次提交。如果您使用 AJAX 表单和/或服务器端,这可以通过 JavaScript 完成。缺点是(正如您自己提到的),它不适用于分布式系统。
使用 JavaScript 检测焦点事件、点击或其他表明您正在与人类打交道的鼠标事件。这个方法在这篇博客文章中有描述(包括一些源代码示例)。
检查用户是否使用标准的网络浏览器;垃圾邮件发送者有时会使用自己编写的程序。您可以检查用户代理字符串,但这很容易操作。特征检测将是另一种可能性。
当然,如果用户禁用了 JavaScript,方法 2-4 将不起作用。<noscript>
例如,在这种情况下,您可以在标签中显示常规验证码。在任何情况下,您都应该始终结合多种方法来获得有效且用户友好的测试。
我最终想到的(在您的特定情况下)是检查输入的电子邮件地址的有效性(不仅在语法上,而且还要检查地址是否真的存在)。这可以通过多种方式完成(请参阅SO 上的这个问题) - 但是,它们都不是真正可靠的。因此,再次,您必须结合不同的方法才能可靠地区分人类和机器人。
假设谁开始向您的网站发送垃圾邮件专门针对您的网站(不是随机垃圾邮件机器人)并且会尝试积极解决所有对策,那么唯一的选择就是某种验证码,因为可以自动避免其他任何事情。
所有防止虚假/垃圾邮件提交的非验证码方法都可以通过利用脚本中的缺陷进行自动提交或分析提交的内容来工作。对于提交的类型,内容分析在这里并不是一个真正的选择。所以剩下的就是用于对抗垃圾邮件评论的各种各样的自动提交预防:
如果攻击者知道它们在那里,则可以绕过这两个 - 例如,当您的网站是选定的而不是随机的目标时。
总而言之:有很多解决方案可以非常成功地阻止随机提交的垃圾邮件,但如果有人专门针对您的网站,唯一可行的就是计算机不擅长的东西 - 验证码。