如何修复ASP.NET系统中reCAPTCHA验证码的漏洞问题
遗留系统reCAPTCHA验证码漏洞修复指引
现有注册页面验证码代码
ASPX页面中使用reCAPTCHA的代码如下:
<div class="col-sm-4 form-group"> <div class="g-recaptcha" data-sitekey="6Ld6ALQUAAAAAAW2GDkJiP9xKrfTvyEVDtYBO-kp"></div> </div>
漏洞扫描发现的问题
- 验证码机制实现薄弱,存在请求绕过风险
- 注册功能的验证码未实现一次性使用机制
漏洞影响
- 违背验证码设计初衷,攻击者可复用同一验证码值批量提交请求
- 恶意用户发送大量垃圾请求,造成服务器资源浪费,增加运维成本
- 注册功能受影响,可能引发批量恶意注册,导致平台账号体系混乱
原修复建议
采用更健壮的CAPTCHA机制(如Google reCAPTCHA),并完成以下优化:
- 编写完善的逻辑判断,区分验证码的有效/无效响应
- 服务器端完成验证码验证,确保无法重复使用
无Burp工具情况下的漏洞复现与修复指引
漏洞复现替代方法
不用Burp也能验证漏洞:
- 正常完成一次注册流程,提交时记录下请求中携带的验证码响应参数(通常是
g-recaptcha-response) - 清空表单(保留刚才记录的验证码参数值),再次提交注册请求
- 若请求成功提交,说明验证码可重复使用;若直接移除验证码参数仍能提交,说明存在绕过漏洞
具体修复步骤(针对ASPX后端)
强制服务器端验证reCAPTCHA
在注册请求的后端处理代码(如.aspx.cs文件)中,添加reCAPTCHA验证逻辑:using System.Net; using System.Web.Script.Serialization; // 获取前端提交的验证码响应 string captchaResponse = Request.Form["g-recaptcha-response"]; if (string.IsNullOrEmpty(captchaResponse)) { // 无验证码响应,直接拒绝请求 Response.Write("请完成验证码验证"); return; } // 向Google reCAPTCHA验证端点发送请求 string secretKey = "你的reCAPTCHA密钥"; // 注意:此密钥需保密,不可暴露在前端 string verificationUrl = $"https://www.google.com/recaptcha/api/siteverify?secret={secretKey}&response={captchaResponse}&remoteip={Request.UserHostAddress}"; using (WebClient client = new WebClient()) { string jsonResult = client.DownloadString(verificationUrl); var result = new JavaScriptSerializer().Deserialize<dynamic>(jsonResult); bool isCaptchaValid = result.success; if (!isCaptchaValid) { // 验证码无效,拒绝请求 Response.Write("验证码验证失败"); return; } }实现验证码一次性使用机制
- 验证通过后,将本次使用的
captchaResponse值存入服务器端存储(如Redis、Session或数据库),标记为已使用 - 每次验证前,先检查该响应值是否已存在于存储中:若存在则直接拒绝,若不存在再进行Google验证
- 注意设置存储的过期时间(如5分钟),避免存储占用过多资源
- 验证通过后,将本次使用的
拦截绕过尝试
- 后端严格校验请求中必须存在
g-recaptcha-response参数,不存在则直接返回错误 - 禁止前端跳过验证码步骤的逻辑,确保所有注册请求都经过验证码验证
- 后端严格校验请求中必须存在
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

