漏洞 6(支撑):从本地文件读取并验证凭证
漏洞 6(支撑):从本地文件读取并验证凭证
代码证据
Login.java 第 77-93 行,凭证验证逻辑:
BufferedReader bufferedReader = new BufferedReader( |
这段代码在做什么
- 打开
credentials.txt - 读出存储的内容:
"Username: alice Password: password123" - 用空格分割字符串
- 提取出存的用户名和密码
- 和用户输入比较
验证逻辑
stored_username == input_username AND stored_password == input_password |
等于:每次都把存在文件里的密码和输入的密码做明文比对。
有什么问题
问题 1:密码明文存储
(在漏洞 5 里已详述) - 如果文件被读取,密码直接暴露
问题 2:没有防暴力破解
- 没有登录次数限制
- 没有账户锁定机制
- 攻击者可以无限次尝试
问题 3:比较是字符串相等
editText2.getText().toString().trim().equals(trim2) |
这行代码做了字符串的直接比较。
如果攻击者知道格式("Username: XXX Password: YYY"): - 可以在文件里改写新的凭证 - 或者通过分析文件格式构造恶意内容
和主漏洞的关系
这个发现在作业里的定位:
| 发现 | 类型 | 定位 |
|---|---|---|
java.util.Random 生成 session token |
CWE-338 | 主漏洞 |
| 明文凭证存储 + 本地验证 | CWE-312 | 支撑发现 |
两者都真实存在于代码里,但:
主漏洞回答的是"随机数用错了"
支撑发现回答的是"凭证存得不够安全"
为什么支撑发现也很重要
即使 session token 的问题被修复了,如果凭证文件是明文存储的:
- 攻击者通过其他途径(如物理访问、恶意软件)拿到文件
- 就能知道用户的用户名和密码
- 然后正常登录
两个漏洞叠加,攻击面更宽。
修复建议
针对这个支撑发现:
不要把密码明文存到文件里,而是:
// 好一点的方案:Hash 存储 |
但最根本的修复还是: - 后端验证(不把密码存在本地) - 但这个 App 没有后端,所以用 EncryptedSharedPreferences 是最实际的方案