验证码设计中常见的安全问题

150 阅读3分钟

验证码 验证码英文缩写为CAPTCHA,即: 完全自动化的公共图灵测试来区分计算机和人类 人机自动识别的图灵测试。 目前,图形验证码已经广泛应用于Web应用程序和客户端软件中。主要用于防止字典攻击(或暴力猜解)、机器注册等。 不幸的是,大多数开发人员都没有注意到这一点,只能应付过去。验证码设计中常见的安全问题有: 验证码有逻辑缺陷,可以被绕过,可以被逆转验证码过于简单,机器无法识别,如下所述。 第一个问题将验证逻辑放在客户端浏览器上 有些系统默认不显示验证码,只有在用户验证错误达到一定次数后才会显示验证码。 那么如何判断用户犯了多少次错误呢?没有经验的开发者可能会这样做: 在cookie中写入一个标志,例如loginErr = 1,然后将随后的错误加起来 问题是,如果攻击者提交没有cookie的HTTP请求怎么办?或者,如果攻击者反复提交而没有更新Cookie中的loginErr值怎么办? 因为程序没有办法获取Cookie/sessionID,所以它会假定攻击者是第一次访问。无论何时,验证码都不会出现! 问题2验证码未过期单个验证码可以重复使用 大多数时候,验证码对应于Web服务器上的会话值。 如果会话经过验证后没有失效,则会重复使用相同的验证码。 此时,验证代码就不再有用了。 攻击者的sessionID和cookie中的sessionID都是固定的一个验证码串,很容易破裂。 另一种常见的代码实现是通过重新下载验证码来更新会话。 开发人员常犯的一个错误是将更新会话的任务留给客户端浏览器。 比如302重定向,甚至可以通过js、meta Refresh重定向页面,引导用户重新下载验证码。 如果用户阻止了重定向,并且不发出新的下载请求怎么办?这种情况下,最后的验证码还能用吗? 基本的认识是:一个验证码,只能使用一次。使用后立即过期,不能再次使用。 问题3向客户端输出验证码 无论什么原因,验证码的内容都不应该被发送到客户端cookie或输出到Response Headers的其他字段。 例如,MD5值和Base64转码写入验证码很容易被反向破解,得到原始值。 即使使用固定的盐,产量也很差。 问题四:验证码太弱 一般来说,有逻辑错误的验证码,还有太弱的通病,使用开源的TessertACT OCR引擎,不需要任何训练,不需要人工噪声处理,就能识别出大部分的互联网验证码! 修正案 1)必须输入验证码。否则必须执行IP策略。小心不要被X-Forwaded For绕过! 2)验证码只能使用一次,且立即失效。不能再用了 3)验证码不能太弱。扭曲,扭曲,干扰线条,干扰背景颜色,改变字体,等等。 4)大型网站最好统一安全验证码,各地使用相同的验证码接口。