浅析图形验证码安全
字数 1331 2025-08-26 22:11:40
图形验证码安全分析与防御指南
验证码概述
验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart"(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
主要作用
- 防止恶意破解密码
- 防止刷票行为
- 防止论坛灌水
- 有效防止暴力破解攻击
验证码基本流程
- 生成验证码图像
- 存储验证码值(通常在服务器端)
- 用户输入验证码
- 服务器验证用户输入与存储值是否匹配
- 验证完成后销毁验证码
常见安全问题及案例分析
1. 验证码使用后未销毁
问题描述:开发人员忘记注销session中存储的验证码,导致验证码可被重复使用。
代码示例:
// 验证码验证后未销毁session
if(strtolower($_REQUEST['captcha'])==$_SESSION['captcha']){
echo '验证码正确';
// 缺少 unset($_SESSION['captcha']);
}
攻击方式:攻击者可截断请求包,重复利用同一个验证码进行爆破攻击。
2. 生成验证码的字符集可控
问题描述:生成验证码的字符集可由外部参数控制,导致验证码可预测。
代码示例:
// 字符集由外部参数控制
$data = isset($_GET['charset']) ? $_GET['charset'] : '0123456789';
案例:ThinkCMF 1.X-2.X版本存在此漏洞,攻击者可指定字符集生成简单验证码。
3. 验证码存放位置暴露
问题描述:验证码明文存储在客户端可访问的位置,如Cookie、隐藏字段等。
代码示例:
// 将验证码存储在Cookie中
setcookie('captcha', $captch_code);
攻击方式:攻击者可直接从Cookie或页面源码中获取验证码值。
4. 验证码对比失败后仍进行其他对比
问题描述:验证码验证失败后未阻断后续流程,仍继续验证用户名密码。
代码示例:
if(strtolower($_REQUEST['captcha'])!=$_SESSION['captcha']){
echo '验证码错误';
// 缺少exit或return
}
// 继续验证用户名密码
checkLogin($_POST['user'], $_POST['pass']);
案例:某KCMS5.0存在类似逻辑漏洞,验证码错误仍可继续验证密码。
5. 其他对比后验证码未销毁
问题描述:验证码在特定条件下未销毁,可能被间接利用。
代码示例:
if(md5($_POST['pass'].$_SESSION['captcha']) == $db_pass){
// 验证通过
}
// 验证码未被销毁
利用方式:可使用常见弱密码反向遍历用户,获取有效账户。
6. 验证码尺寸可控
问题描述:验证码图像尺寸由外部参数控制,可能导致资源耗尽攻击。
代码示例:
$width = isset($_GET['w']) ? $_GET['w'] : 100;
$height = isset($_GET['h']) ? $_GET['h'] : 30;
$image = imagecreatetruecolor($width, $height);
案例:PHPcms早期版本存在此漏洞,可构造超大尺寸验证码导致服务器资源耗尽。
7. 验证码过于简单
问题描述:验证码设计过于简单,可被OCR技术轻易识别。
常见问题:
- 纯数字验证码
- 无干扰线或噪点
- 固定字体和位置
- 低复杂度背景
识别实例:简单的4位数字验证码可通过图像处理技术轻松识别。
安全防御建议
-
验证码复杂度
- 使用6位以上混合字符(数字+字母大小写)
- 添加干扰线、噪点和扭曲变形
- 使用随机字体和位置
-
验证流程
- 优先验证验证码,失败时立即终止后续验证
- 验证后立即销毁session中的验证码
- 设置验证码有效期(建议1分钟)
-
存储安全
- 验证码只存储在服务器端session中
- 禁止将验证码存储在Cookie或客户端
-
防自动化
- 限制单位时间内验证码尝试次数
- 对频繁错误请求实施临时封禁
- 考虑使用行为验证码替代传统图形验证码
-
资源控制
- 固定验证码图像尺寸
- 限制验证码生成频率
- 对异常尺寸请求进行过滤
实际应用现状
在企事业单位业务系统中,验证码安全问题普遍存在,常见现象包括:
- 验证码仅前端展示,后端不验证
- 简单4位数字验证码
- 验证码可重复使用
- 验证码逻辑存在缺陷
安全人员应重点关注验证码的实现逻辑而不仅是表面复杂度,许多系统看似有验证码保护,实则存在严重逻辑缺陷。