最近我在的城市疫情有点严重,连续被捅了8次嗓子,在某次查询核酸结果的时候,我发现了查询网站好像不那么安全,于是开始了研究。
漏洞发现

在查询核酸检测结果时,发现每次请求的API参数是相同的,并且请求无需通过验证。那么,这里的验证码很可能只有前端验证,后端并没有进行验证,并且加密算法是固定的。只要知道是如何加密的,就可以直接通过身份证号查询到公民信息。
加密算法
通过F12
,发现接口发送的参数为IdCard
。在所有的JS
文件中搜索IdCard
,排除掉几个无用的文件后,发现了真正发送数据的JS
文件。

1 | this.resultList = [], this.idCode = "", T("******", { |
把这个JS
文件直接下载到本地进行分析,按住Ctrl
点变量s
,追踪到s
是由O
函数得到的。
1 | var e = this, |
O
函数的功能是对输入的身份证进行AES
加密,返回的密码被发送到接口。这里的AES
加密模式为ECB
,Pkcs7
填充,在O
函数的上方,还发现了密钥。
1 | var A = CryptoJS.enc.Utf8.parse("******"); |
验证
由于O
函数位于闭包函数内,不便于调用,所以将用于加密的aes.js
文件下载到本地,然后在控制台直接调用O
函数得到密文。
再将密文直接发送到接口,得到公民信息。

此网站还有个功能为通过二维码批量获取核酸检测结果,猜测开发者为了省事,后端没有对验证码和请求频率进行限制,从而增加了泄露公民信息的隐患。
修复建议
- 验证码采用后端验证的方式。
- 接口仅返回必要信息。
- 后端限制请求频率,避免大规模的信息泄露。
- 验证姓名是否与身份证匹配。
后续

有关部门很积极地处理了本次事件,目前已经将平台升级,验证码采用后端验证的方式,接口仅返回必要信息。
