wallet-security-review
在区块链钱包相关代码变更前,对照下方检查清单进行安全审查,尽早发现可能导致资产损失、密钥泄露或用户体验劣化的问题。
何时使用
- 项目为区块链钱包相关项目(浏览器插件、Web/H5、App 内嵌 WebView、桌面客户端等形态均适用)
- 用户角色为区块链钱包开发者,或在 CI/CD 流水线中自动运行
- 存在非文档类代码变更(如
.ts/.js/.tsx/.vue/.sol等)时触发 - 默认对比
master/main分支的 git diff 变更范围进行扫描;用户可指定其他 base branch
审查流程
- 确定对比基准:默认为
master/main,可由用户指定其他 base branch 或 commit range 覆盖。 - 逐文件、逐 hunk 比对下方「检查清单」,记录命中的规则编号(如
C4)与严重级别。 - 无法仅凭代码判断意图或实际影响范围的项,在报告中标记为「需人工确认」,不要直接判定通过或不通过。
- 按「输出报告」的模板在当前仓库根目录生成
wallet-security-review-YYYYMMDDHHmmss.md,并在对话中简要总结 P0 数量与最关键的 1-3 个风险点。 - 涉及 UI 展示或交互体验的 P1/P2 项(尤其是 H 类),在报告中额外标注「需同步 PM / UI-UX」。
严重级别
- P0 ⛔️ 高危,必须修复:可能直接导致资产损失、密钥/助记词泄露、任意转账或被钓鱼
- P1 ⚠️ 中危,建议修复:存在资损或安全隐患,但需要特定条件触发,或影响面/概率较小
- P2 💡 提示,体验与健壮性:不直接导致资损,但影响用户体验或系统健壮性,通常需与 PM / UI-UX 协同处理
检查清单
A. 密钥与敏感数据安全
- A1 ⛔️ 助记词/私钥在内存中明文存在时间过长,使用后应尽快清零/覆盖
- A2 ⛔️ 仅做了简单加密,未评估算法健壮性(弱算法、ECB 模式、固定 IV 等)
- A3 ⛔️ 密码未加密存储(本地持久化应加盐哈希,而非明文或简单编码)
- A4 ⛔️ 助记词/私钥导出经由带浏览器缓存的表单元素(input/textarea)中转,而非仅存在于内存变量或 canvas 绘制中
- A5 ⛔️ 导入助记词/私钥后未清空剪贴板
- A6 ⛔️ 安全随机数不够随机(未使用 CSPRNG,如密钥/助记词生成用了
Math.random) - A7 ⛔️ 密钥派生路径(derivation path)配置错误
- A8 ⛔️ MPC 密钥分片(share)本地存储的加密强度与访问控制未达到与完整私钥同等的安全级别
- A9 ⚠️ 助记词/私钥对象未重写
toString/toJSON,可能被间接打印、序列化或误上报到日志系统 - A10 ⚠️ 助记词导入时未做 BIP39 校验和与词库合法性校验,错误助记词被静默接受
- A11 ⚠️ Keystore/JSON 等密钥文件导入未做格式与来源的严格校验
- A12 💡 助记词展示页面未做防截屏/录屏保护
- A13 💡 本地密码/生物识别校验未与密钥解锁强绑定,存在被前端层面绕过的风险
B. 数值精度与计算安全
- B1 ⛔️ 小数点放大/缩小换算错误,导致金额数量级错误
- B2 ⛔️ 小数点位数被截断,导致用户输入值与实际参与计算/展示的值不一致(如
0.123456789被截断为0.12345678而未察觉) - B3 ⛔️ 使用
Number类型做金额运算,未使用BigInt/BigNumber等高精度方案 - B4 ⛔️ 数据经过中间格式转换后再转换回来,结果不一致(字符串⇄浮点数⇄链上最小单位往返丢精度)
- B5 ⛔️ 使用四舍五入处理金额(链上通常应向下取整/截断,四舍五入可能导致多转/透支)
- B6 ⚠️ 代码中存在多个 BigNumber 实例(版本或库不一致),可能导致类型不兼容
- B7 ⚠️ 多处 BigNumber 使用未统一设置最大精度(如
DECIMAL_PLACES) - B8 ⚠️ UI 展示的金额(如约 1 ETH)与实际参与签名的精确值(如 0.9998 ETH)不一致,用户基于展示值编辑后产生偏差
- B9 ⚠️ 多币种/多链 decimals 未按代币实际精度处理(如误把非 18 位小数代币当作 18 位)
- B10 💡 数值进制转换错误,如把十六进制字面量
0x101误按十进制101解析(或反之) - B11 💡 不同 locale 的数字本地化格式(千分位、小数点符号)导致金额被误读
C. 交易安全与风控
- C1 ⛔️ 转账/授权目标地址未做黑灰名单检查
- C2 ⛔️ chainId 与其十六进制形式之间转换错误,可能在错误的链上签名/广播
- C3 ⛔️ 非同构链的跨链收款地址派生/展示错误
- C4 ⛔️
eth_sign等高危签名方法未禁用或未做额外风险拦截 - C5 ⛔️ 盲签场景下未向用户展示签名的实际内容(calldata / 消息原文)
- C6 ⛔️ EIP-4337 UserOperation 中
paymaster、validUntil/validAfter、gas 相关字段的客户端展示与实际参与签名的值不一致 - C7 ⛔️ EIP-7702 Authorization(delegate 合约地址)签名前未完整展示委托目标,或未校验目标合约来源可信度
- C8 ⚠️ 快速重复点击未做 loading 态拦截,导致重复转账
- C9 ⚠️ 询价(quote)接口未做防抖/拦截,短时间内重复请求
- C10 ⚠️ gas 费用异常过大时未做拦截或二次确认
- C11 ⚠️ 卡住的 nonce 未提供替换(加速/取消)交易的能力
- C12 ⚠️ 加速交易时未携带原始 calldata,导致语义变化
- C13 ⚠️ 取消交易时资金流向未确保发送给自己(同地址 0 值自转账)
- C14 ⚠️ 并发发起多笔交易时未考虑 nonce 时序,导致相互覆盖或卡死
- C15 ⚠️ gas 预估阶段使用了真实私钥签名(gas 预估无需真实签名,非必要使用真实签名会扩大私钥暴露面)
- C16 ⚠️ 交易广播失败后的重试未做幂等处理,可能导致重复扣款
- C17 💡 未对夹子攻击(三明治攻击/抢跑)风险做用户提示(滑点保护、私有交易通道等)
- C18 💡 RPC 节点返回的余额/交易状态等数据未做合理性校验,无法识别被劫持或恶意 RPC 返回的虚假数据
- C19 💡 重放攻击防护缺失,同一签名可能在不同网络/环境下被重复提交
D. dapp 交互与授权安全
- D1 ⛔️ 授权(approve)操作未做额度/合约来源检查
- D2 ⛔️ dapp 可直接触发签名,未经过用户显式确认/授权弹窗
- D3 ⛔️ 内部方法或敏感属性未做隔离,被意外暴露给 dapp 可调用
- D4 ⛔️ dapp 域名白名单校验过于宽松(如用
includes模糊匹配,导致uniswap.app匹配到myuniswap.app等钓鱼域名绕过) - D5 ⚠️ 受保护接口(如 ENS 域名查询)未做参数注入检测
- D6 ⚠️ 交易 calldata 未做反解析校验,用户看到的"意图"与实际执行的 calldata 不一致
- D7 ⚠️ 路由未做权限拦截,可能绕过校验直接访问敏感页面/操作
- D8 ⚠️ WalletConnect / 深度链接(Deep Link)参数未做合法性与来源校验
- D9 ⚠️ MPC/多签签名协同过程中,各参与方通信未做身份校验,存在中间人篡改签名请求的风险
- D10 💡 发起无限额度(Unlimited Approval)授权时未提示风险或未提供自定义额度选项
- D11 💡 WebView 内嵌 JSBridge 暴露的方法未做调用来源(origin)校验
- D12 💡 多签/MPC 场景下参与方数量与签名阈值未做客户端二次校验
E. 供应链与配置安全
- E1 ⛔️ 引入依赖未做白名单/来源审查,存在供应链投毒风险
- E2 ⛔️ 环境变量、私有 RPC 地址、测试私钥等敏感配置被硬编码写入代码仓库
- E3 ⚠️ 关键地址(DEX router、合约地址、收款地址等)写死在代码中
- E4 ⚠️ 使用了过时、存在已知攻击案例的 npm 包
- E5 ⚠️ 使用了缺乏维护、使用者稀少的 npm 包,存在被接管或无法替换的风险
- E6 💡 依赖安装/构建脚本(如 postinstall)未审查,可能执行任意代码
- E7 💡 发布产物未做完整性校验(如 hash / 签名校验),无法发现被篡改的构建产物
F. 信息泄露与日志安全
- F1 ⛔️ 报错信息中的敏感数据泄漏到 Sentry 等第三方监控平台
- F2 ⛔️ 报错信息中的敏感数据泄漏给 dapp
- F3 ⛔️ 应用崩溃时在屏幕上输出了敏感信息,或生成了包含敏感信息的日志/崩溃报告
- F4 ⚠️ 生产环境控制台(console)未清空,打印了敏感信息
- F5 ⚠️ 日志中包含地址以外的、可关联用户身份的个人信息并被上报
- F6 💡 埋点/统计 SDK 上报数据中包含超出必要范围的可关联用户信息
G. 状态持久化与稳定性
- G1 ⚠️ 持久化数据读写异常未做校验,出错后不可恢复
- G2 ⚠️ 版本更新后旧数据不兼容(如 cointype 配置错误),且没有迁移机制,导致错误一直延续
- G3 ⛔️ 页面状态恢复(如重新打开)时,遗留的临时数据未清空,导致以错误金额发起转账
- G4 ⚠️ 页面崩溃/报错导致用户无法进行下一步操作(转账、切换网络等),未提供自行恢复的路径
- G5 ⚠️ 耗时计算(如 BTC 手续费计算、MPC 签名过程)阻塞主线程,页面卡死且无进度提示
- G6 💡 多标签页/多实例并发操作同一钱包状态未做互斥或同步,可能导致状态错乱(如 nonce、余额缓存)
- G7 💡 应用进入后台或锁屏后未做自动锁定/内容遮罩,多任务预览可能泄露地址、余额等信息
H. UI 展示与用户体验安全
- H1 ⛔️ 关键信息(如金额)在 UI 上被截断显示,导致用户误判后转账
- H2 ⚠️ 深色模式/极端字体缩放/多语言场景下,金额、地址等关键信息被截断或换行错位而未被察觉
- H3 💡 地址展示未对易混淆字符(如
0/O、1/l)或校验位做高亮提示,用户核对地址时容易看错
输出报告
输出文件命名:wallet-security-review-YYYYMMDDHHmmss.md(如 wallet-security-review-20260814152340.md),默认输出到当前仓库根目录。
模板
钱包安全开发审查报告 - ${日期}
对比范围:${base_branch} → ${target_branch_or_commit}
变更文件数:${N}
## P0 ⛔️ 高危(必须修复)
### ${分类} · ${规则编号} ${规则简述}
- 位置:${文件路径}:${行号}
- 问题:${具体问题描述}
- 风险:${可能导致的后果}
- 建议:${修改建议}
## P1 ⚠️ 中危(建议修复)
(结构同上)
## P2 💡 提示(体验/健壮性,需同步 PM / UI-UX)
(结构同上)
## 需人工确认
${无法仅凭代码判断意图或影响范围的情况,列出文件位置与需要确认的问题}