# 安全说明 ## 漏洞报告 发现安全问题请**不要**直接开公开 Issue(可能包含可利用细节)。联系渠道: - 仓库主页留下联系方式的维护者(站内私信 / Issues 留言板) - 紧急情况可直接在描述安全隐患的前提下开 Issue 标注 `security`,我们会尽快下线和修复 处理流程:收到报告 → 48 小时内确认 → 评估影响并给出缓解策略 → 修复发版 → 在 `CHANGELOG.md` 的 `Security` 段致谢公示。 ## 安全模型(威胁模型摘要) 数据全走 HTTPS + Bearer Token,服务器为多用户托管形态,按用户强制隔离——信任边界假设 「攻击者 = 其他注册用户 / 网络中间人 / 触碰 GET 接口的匿名流量」。 | 面 | 现状 | |---|---| | 认证算法 | scrypt(随机 16B 盐)+ `timingSafeEqual`,官方 crypto 原语,无自造算法 | | Token | 服务端 32 字节随机 hex 存储 + 365 天过期;登录后同设备复用 device_id;支持 `/auth/logout` 服务端吊销 | | 类似爆破的防护 | 登录:同 IP+用户名连续失败 5 次 → 冷却 10 分钟(进程内计数) | | 按用户数据隔离 | `commandsFor(user_id)` 每用户一份独立 `users/.db`;跨库读取天然命中"不存在",实测经 /api 与 /sync 均无法跨读 | | 管理 API | 统一双重校验:登录态 + is_admin;自删与"最后管理员"禁删 | | SQL 注入 | 全部参数化;`ORDER BY` 走白名单(`SORTS` 表);FTS MATCH 参数传入、字符串仅做双引号包裹 | | 路径注入/XSS | 上传文件名剥离 `\\/:*?"<>|` + UUID 前缀;附件文件名以 **SHA-256 命名**(无文件系统注入位);前端 `dangerouslySetInnerHTML` 有且仅两处(一处全转义、一处白名单净化 docx/xlsx 预览) | | 注册准入 | `REGISTER_ENABLED`、`INVITE_CODE`(或管理页动态码)、`MAX_USERS` 三道门控,服务端强制(客户端传的 `seed` 播种标志一律剥离,防止绕过邀请码/配额/自动升级管理员规则) | | 附件上传 | SHA-256 声明校验 + 100MB 上限;下载统一 `Cache-Control: private, immutable`(跨账号缓存隔离) | | 客户端依赖 | 服务器**零 npm 依赖**(仅 Node 内置模块),规避供应链攻击面 | | CORS | `Access-Control-Allow-Origin: *`。凭据仅 localStorage Bearer、不用 Cookie,不放大 CSRF 面;如有同源严格化诉求欢迎提案 | | 审计日志 | 图床清理、用户删除、demo 重建等敏感操作写标准日志(容器 stdout) | ## 已知设计取舍 - Token 存放浏览器 `localStorage`(XSS 可及):与多端 token 缓存目录一致;服务端可能追加 CSP 响应头、可加入 HttpOnly Cookie 会话机制(改动契约,暂未引入) - 限速是进程内存态,重启清零;RLS 想要更强的反爆破可以套容器内的 fail2ban / Cloudflare 规则 - 备份文件内含用户档案明文,请按敏感数据管理 ## 上线运维要点(契约要求) - 首个真实账号注册后关闭 `REGISTER_ENABLED`,改掉 `INVITE_CODE` 示例默认值 - `./data/` 目录备份(含 `-wal`/`-shm`) - 服务端公网面只暴露 443(Caddy TLS 到 sync-server)