找回密码
 立即注册
搜索
人人必备的 Wise 💳最便宜的 eSIM 流量手机号 📱帕劳身份证 🆔
查看: 69|回复: 1

【避坑】myEquifax 邮寄验证码页提交没反应?是官网前端的竞态 Bug,附根因

[复制链接]
sunfase 发表于 昨天 10:40 | 显示全部楼层 |阅读模式

注册免广告

您需要 登录 才可以下载或查看,没有账号?立即注册

×
如果你在办 myEquifax 注册,走到「邮寄验证码」这一步(就是 Equifax 给你寄信、信上有个 10 位验证码那个),在 https://my.equifax.com/pin 填完邮箱和验证码,点 Continue 完全没反应——不跳转、不报错、什么都不发生。

先说结论:不是你填错了,是 Equifax 官网自己的前端 Bug。

我把页面打包后的 JS 反编译扒了一遍,定位到了根因,也写了个能用的修复脚本,分享出来给同样卡住的朋友。

一、现象

  • 邮箱和验证码都填对了
  • 点 Continue 按钮,毫无反应
  • F12 打开网络面板,根本没有任何提交请求发出,只有 Datadog、Optimizely 那些第三方埋点在跑


就是说请求在浏览器这一端就被拦住了,压根没到 Equifax 服务器。换浏览器、换设备、清 Cookie 都没用(我 Chrome 和 Safari 都试过)。

二、根因

页面是 Angular 写的。表单其实有三个字段,第三个是页面上看不见的隐藏必填项:

  1. this.ptpSubmitPinForm = this.formBuilder.group({
  2.   emailAddress: ["", [required, pattern(...)]],
  3.   pin:          ["", [required, minLength(10), maxLength(10), pattern("^[A-Z0-9]{10}$")]],
  4.   reCaptcha:    ["", this.recaptchaEnterpriseV3Enabled ? [] : [required]]
  5. })
复制代码


再看提交函数,两条分支全是静默 return,不给任何提示:

  1. submitForm = async () => {
  2.   if (this.recaptchaEnterpriseV3Enabled) {
  3.     if ("VALID" !== this.ptpSubmitPinForm.status)
  4.       return void markAllAsTouched();                    // ← 静默 return
  5.     if (!(this.siteKey$ && typeof window.grecaptcha < "u" && window.grecaptcha.enterprise))
  6.       return void (this.showCaptchaError = true);        // ← 静默 return
  7.   } else if ("VALID" !== this.ptpSubmitPinForm.status) {
  8.     return;                                              // ← 静默 return
  9.   }
  10.   // ...
  11.   this.ptpService.submitPtpPin(B, F, z).subscribe(...)   // 真正的提交,永远走不到
  12. }
复制代码


问题出在 ngOnInit 的执行顺序上——这是个典型的竞态:

  1. ngOnInit() {
  2.   this.loadAppConfigurationDetails(),   // ① 异步 HTTP,回来后才给 recaptchaEnterpriseV3Enabled 赋值
  3.   this.getNewDesign(),
  4.   this.getProductOfferDetails(),
  5.   this.createCaptchaTestingHook(),
  6.   this.recaptchaEnterpriseV3Enabled && (              // ② 同步执行,此刻还是 undefined!
  7.       this.ptpSubmitPinForm.get("reCaptcha")?.clearValidators(),
  8.       this.ptpSubmitPinForm.get("reCaptcha")?.updateValueAndValidity()),
  9.   this.captchaService.retrieveCaptchaSiteKey("ptp-submit-pin").subscribe(e => {
  10.       this.siteKey$ = e.siteKey,
  11.       this.recaptchaEnterpriseV3Enabled && this.loadRecaptchaV3Script()   // ③ 同样赶在①前面
  12.   }, e => {})
  13. }
复制代码


② 和 ③ 都跑在 ① 的 HTTP 响应回来之前,那时候 recaptchaEnterpriseV3Enabled 还是 undefined(假值),于是:

  • ② 的 clearValidators() 没执行 → reCaptcha 字段的 required 校验保留着
  • ③ 的 loadRecaptchaV3Script() 没执行 → reCAPTCHA 脚本从头到尾就没加载过


死锁就这么形成了:

检查项实际状态
window.grecaptcha存在(页面加载的是 v2 的 api.js)
window.grecaptcha.enterpriseundefined
recaptcha-v3-script 元素不存在
DOM 里的 reCAPTCHA 组件没渲染(表单只有邮箱、验证码、按钮三个子元素)
reCaptcha 表单字段永远为空,但带 required


等 ① 的响应回来把开关置成 true 的时候已经晚了:提交时走 enterprise 分支,却发现表单是 invalid,第一道检查就 return 了。

验证证据:填入合法的邮箱和验证码后,两个输入框自己都是 ng-valid,但表单整体是 ng-invalid。我只往 reCaptcha 字段塞了个任意值,表单立刻变成 ng-valid——确认它就是唯一的拦路虎。

evidence-bug2_2026-07-26T02-25-22-157Z.png
填入合法邮箱和验证码后的 DevTools 诊断:两个输入框各自 ng-valid,表单整体却是 ng-invalid

服务端接口本身完全正常,captchaSiteKey 和 appConfig 都返回 200,appConfig 里 recaptchaEnterpriseV3Enabled 明明白白是 true。纯粹是前端加载时序写挂了。

另外提醒一个坑:这个站点密钥是 Enterprise / v3 类型。我一开始想当然用 v2 的 grecaptcha.render() 去渲染那个「我不是机器人」复选框,结果报「密钥类型无效 / Invalid key type」。v3 是无感知验证,本来就没有复选框可点,别走弯路。

三、修复思路

很简单——把页面因为竞态而漏掉的那一步手动补上

  • 手动注入 https://www.google.com/recaptcha/enterprise.js?render=<siteKey>
  • 轮询等 grecaptcha.enterprise.execute 就绪
  • 调 grecaptcha.enterprise.execute(KEY, { action: 'register' }) 拿 token
  • 通过页面自己注册的 window.setCaptchaValue(token) 写进表单,触发变更检测


这里说明一下:setCaptchaValue 是页面源码里 createCaptchaTestingHook() 主动挂到 window 上的官方钩子,不是外部硬塞的。token 也是 Google 正常签发的(实测 2400+ 字符)。不涉及任何伪造或绕过风控——服务端的验证码校验、尝试次数限制这些都原封不动保留着,脚本干的只是补齐页面自己没做完的初始化。

实测效果:注入脚本后 831ms,grecaptcha.enterprise 就绪,拿到 token 灌进去,表单从 ng-invalid 变成 ng-valid,提交请求正常发出。

evidence-fixed_2026-07-26T02-26-21-687Z.png
运行修复脚本后的同一页面:form#idForm 变为 ng-valid,Continue 可正常提交

四、项目地址

代码和完整分析都放 GitHub 了,MIT 协议:

https://github.com/sunfase-io/equifax-pin-captcha-fix

五、怎么用

  • 打开 https://my.equifax.com/pin
  • 先把邮箱和 10 位验证码填好
  • F12 打开 DevTools,切到 Console
  • 首次用 Chrome 会让你手输 allow pasting 再回车(只需一次)
  • 把仓库里 equifax-fix.js 全文复制粘贴进 Console,回车
  • 页面顶部出现绿色横幅「reCAPTCHA 已就绪」后,手动点 Continue


几个注意事项:

  • 先关掉 Requestly 之类的 HTTP 拦截扩展,它们可能干扰 reCAPTCHA 脚本加载,很可能就是诱因之一
  • token 有效期大概 2 分钟,横幅出来后尽快点 Continue,超时了就重跑一遍脚本
  • 得能正常访问 google.com,Enterprise 脚本是直接从 Google 那边加载的
  • 脚本不会自动帮你提交。页面有 remainingAttempts 机制,验证码填错次数用完会被强制踢到客服页,所以提交这一步留给你自己确认无误后再点
  • 验证码正则是 ^[A-Z0-9]{10}$,大写字母和数字都放行。填错前端不拦,会直接消耗一次机会——信是扫描件的话,注意分辨 O 和 0、Q 和 O 这些易混字符


六、其他

分析环境是 Chrome 150,2026 年 7 月验证通过。Equifax 前端更新后脚本可能失效。如果 siteKey 变了,从 GET /consumer-registration/rest/1.0/captchaSiteKey?pageName=ptp-submit-pin 的响应里取新值,替换脚本里的 KEY 常量就行。

如果实在搞不定,也可以直接打客服电话 888-836-6351(周一到周五 8a-9p EST),跟他们说「网站 PIN 提交页的 reCAPTCHA 加载不出来,Continue 按钮没反应」,让客服在后台帮你完成验证。

希望能帮到卡在这一步的朋友。有问题欢迎回帖交流。
如果帖子/回帖帮助到你,请给作者评分/点赞
HackerTerry 发表于 昨天 23:20 | 显示全部楼层
好专业,看不懂,收藏支持
如果帖子/回帖帮助到你,请给作者评分/点赞
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

排行榜|意见建议|黑名单|数字居民论坛

GMT+8, 2026-7-27 05:14

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表