安全¶
隐私红线:手机号永不落明文¶
唯一存储形式:HMAC-SHA256(phone, HMAC_KEY)。
- 查询时按 hmac 对比;展示时用
138****1111掩码 - stdout / stderr / vault / 日志 / 备份里都不能出现明文手机号
- 测试里有 red-line assert 守护(
grep -r '138001' src/ test/必须 0 命中)
凭证:vault 声明式¶
- 所有敏感凭证(阿里云 AK / 短信 AK / 支付宝证书)只存 vault
- 代码不读 env
*_SECRET(避 systemd env 打印) - 走
.vault/secrets.json(权限 600),代码json.load一次性取
详见 接入 vault。
服务降权¶
systemd unit 强约束:
User=xiangqin
# system user,/sbin/nologin
ProtectSystem=strict
ProtectHome=true
NoNewPrivileges=true
PrivateTmp=true
只有 /opt/xiangqin/data/ 可写(sqlite)。
网络:端口收窄¶
阿里云安全组只开:
- 22(SSH)
- 80 / 443(HTTP/S)
关掉的遗留端口(来自 openclaw 时代):7000 / 9876 / 22000-22999 / 内网 5432。
支付宝回调验签¶
/exposure/webhook/alipay endpoint 强制:
- 用
alipay_public_key验 RSA2 签名 - 验
app_id匹配 - 验
out_trade_no对得上订单 - 原子充值(
UPDATE ... WHERE paid=0,防重放)
验签失败返回 fail(支付宝会重试最多 7 次,7 次内不修复就人工处理)。
数据层¶
- sqlite WAL 模式 +
PRAGMA foreign_keys=ON - 每日 02:00 OSS 备份(保留 30 天)
- 恢复演练每月跑一次(见 运维)
客户端 session¶
- 存
~/.xiangqin/session.json,权限 600 - 逻辑在
src/xiangqin/client_session.py xq logout删本地 + 调服务端/auth/logout让 token 立即失效
审计¶
- 所有变更记 ADR
- CI 跑
gitleaks(未来加)扫秘密 vault check在 pre-commit 守护,引用悬空 block commit
威胁模型(不覆盖的)¶
xiangqin 不防御:
- ❌ 手机号用户侧被钓鱼(用户泄露自己手机号 → 验证码冒领)
- ❌ 支付宝账号被盗(扣款归支付宝责任)
- ❌ epsilon 被完全接管(整机被黑是上游问题)
防御范围:xiangqin 代码 + 数据不主动泄露用户敏感信息。