在过去的三年中,Doyensec为全球知名加密货币项目提供安全测试服务,审计范围涵盖桌面/移动钱包、交易所Web界面、托管系统及核心基础设施组件。我们既见证了优秀实践,也发现了诸多设计与实现漏洞。失败是最好的安全教材,本文将通过四个典型案例揭示看似简单却危害巨大的漏洞模式。
1) CORS配置错误
跨域资源共享(CORS)机制用于放宽同源策略,但其错误配置会导致严重安全问题。例如当服务端返回以下头信息时:
1
2
|
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
|
攻击者可通过特制页面窃取用户密钥:
1
2
3
4
5
6
7
|
<iframe sandbox="allow-scripts" src="https://attacker.com/corsbug" />
<script>
var req = new XMLHttpRequest();
req.open('GET', 'https://bitcoinbank/keys', true);
req.withCredentials = true;
req.send();
</script>
|
防御清单:
- 禁止将
Access-Control-Allow-Origin
设为null
- 避免从用户可控变量生成CORS头
- 禁止动态复制
Origin
头值
2) 断言与编译器陷阱
某些语言的编译器优化会产生意外行为。例如Python的assert语句在生产环境(.pyo
文件)会被完全移除:
1
|
assert all([x.deposit_address == address for x in deposits]) # 生产环境失效
|
Swift中若使用assertionFailure
进行密码校验,在发布版本(-O
优化)时检查也会被移除:
1
2
3
|
if (password != "mysecretpw") {
assertionFailure("Password not correct!") // 发布版本跳过校验
}
|
防御清单:
- 禁止使用assert进行安全控制
- 深入研究所用语言的编译器特性
3) 算术运算漏洞
金融系统中数值处理不当可能引发致命错误。例如允许负数的提现操作:
1
2
3
|
if data["wallet"].balance < data["amount"]: # 未校验amount>0
error_dict["wallet_balance"] = ("Withdrawal exceeds available balance")
data["wallet"].balance = 200 - (-100) # 余额反而增加300
|
有符号整数溢出同样危险:
1
2
|
signed short int bank_account = -30000;
bank_account -= 2769; // 溢出后余额变为32767
|
防御清单:
4) Referer头泄露密码重置令牌
密码重置链接中的令牌常通过Referer头泄露给第三方域名:
1
2
3
|
GET /libs/jquery.js HTTP/1.1
Host: 3rdpartyexampledomain.com
Referer: https://example.com/passwordreset/2a8c5d7e-5c2c-4ea6-9894-b18436ea5320
|
防御方案:
- 使用
<meta name="referrer" content="no-referrer" />
- 设置
Referrer-Policy
响应头
- 通过空白中转页跳转
如需平台安全评估服务,请联系info@doyensec.com!