Skip to content

Security: SHIN09-git/doc-manager

Security

SECURITY.md

安全与隐私

依赖维护

使用 npm ci 安装锁定依赖,使用 npm audit 复查已知告警。pptxgenjs 的间接依赖 image-size 暂时覆盖为 2.0.4,以修复旧解析器处理部分图片格式时的无限循环问题。升级 pptxgenjs 后应复核是否仍需该覆盖;当前原生 PPTX 导出由 test/pptxBuilder.test.js 验证。

后台运营权限边界

  • 组织后台的 /api/ops/recent-errors 只返回当前组织归属的系统事件和 AI 失败记录,不返回 organization_id === null 的平台级全局事件。
  • 组织管理员只能通过 /api/ops/events/:id/triage 跟进当前组织的事件或当前组织的 AI 失败记录;平台级事件会返回 404。
  • AI 失败记录的跟进信息保存在 ops_triage,与 ai_usage 原始用量记录分离,避免把运营处理备注混入用量事实。
  • 后台个人偏好保存在 admin_preferences,按 organization_id + user_id 隔离;审计筛选、错误筛选和反馈筛选不会跨组织串用。
  • 组织数据导出会包含本组织的 ops_triage 和 admin_preferences,用于审计留档;个人数据导出只包含当前用户更新过的跟进偏好记录。

摹文拟笔工作台默认本地优先,但它会在你主动调用 AI 时把相关内容发送到你配置的 AI 服务。使用真实材料前,请先确认数据规范和接口来源。

数据存在哪里

默认情况下:

  • 文档、执笔人、版本、垃圾箱和设置主要保存在浏览器 IndexedDB。
  • localStorage 只作为启动缓存、旧数据兼容和轻量兜底。
  • 真实文件夹关联依赖浏览器 File System Access API 授权。
  • 项目没有内置后端,不会把数据上传给项目作者。

更换浏览器、清理站点数据或使用隐私模式,可能导致本地数据丢失。请定期导出备份。

API Key

AI 接口配置保存在当前浏览器。

请注意:

  • 不要把 API Key 写进仓库。
  • 不要把包含 API Key 的截图提交到 Issue。
  • 团队部署时建议使用后端代理统一管理密钥、额度和审计。云端模式下,组织 API Key 使用 AES-GCM 加密保存,接口只返回 key_hint。

云端模式安全

云端模式是可选能力。生产环境部署时请至少做到:

  • 设置强 APP_ENCRYPTION_SECRET 和 SESSION_SECRET,长度不少于 32 个字符。
  • 设置明确的 CORS_ORIGIN,不要在生产环境使用通配来源。
  • 前端与 API 优先使用同一站点下的子域并保持 SESSION_SAME_SITE=Lax;跨站部署使用 None 时必须同时启用 SESSION_SECURE=true,并做第三方 Cookie 兼容验证。
  • 生产环境下,Cookie 认证的 POST、PUT、PATCH、DELETE 请求必须带可信 Origin 或 Referer;脚本、运维工具和服务端集成应改用 Authorization: Bearer <session-token>。
  • 本地开发可使用 STORE_DRIVER=json;生产默认强制 PostgreSQL,ALLOW_PRODUCTION_JSON_STORE=true 只应用于明确接受单机文件风险的临时应急场景。
  • 定期备份云端数据,尤其是文档、执笔人、版本和审计日志。
  • 云端敏感管理操作要求邮箱验证。
  • 登录失败会触发短时节流。
  • 忘记密码和邮箱验证使用一次性令牌,生产环境不在 API 响应中暴露令牌,且必须通过邮件 webhook 投递。
  • 邮箱验证和密码重置的提交阶段会把未知邮箱和错误令牌统一反馈为“无效或已过期”,避免公开认证入口被用来枚举账号。
  • 邮件发送可使用通用 HTTP webhook 或 Resend 适配;EMAIL_RESEND_API_KEY、EMAIL_WEBHOOK_TOKEN 和 EMAIL_CALLBACK_TOKEN 都应作为生产密钥管理,不应提交到仓库或前端代码。
  • 邀请成员时只把邀请码发给目标邮箱对应的用户,接受邀请需要匹配邀请码。
  • 生产 JSON 配置不应依赖静默兜底;AI_COST_RATES、PAYMENT_PLAN_PRICE_MAP 和 MANUAL_PAYMENT_PACKAGES 一旦填写,启动时必须解析为正确的 JSON 对象或数组,避免价格映射、套餐或成本配置无声失效。
  • 支付 webhook 使用 HMAC 签名和时间戳校验,错误签名、过期请求和重复事件会被拒绝或幂等处理。正式接支付渠道时,应通过 PAYMENT_PLAN_PRICE_MAP 将渠道价格 ID 映射到内部套餐,不要信任 webhook 中可伪造的原始 plan 字段。
  • 支付 webhook 原始 payload 只在后端内部留存用于排查和审计;账单摘要、管理员后台、组织导出和 webhook 响应只返回脱敏摘要,不应把渠道回调原文直接透出给前端。
  • 邮件投递记录的公开 metadata 只保留投递排查必要字段,例如 delivery_id、message_id、回调状态和回调时间;验证码、重置码、内部验证 ID 或任意 secret 不应出现在管理员后台和组织导出中。
  • 系统事件和最近错误的公开 metadata 会递归隐藏 token、secret、password、api_key、authorization、cookie、signature 等敏感键;新增运营事件时仍应避免把真实密钥写入事件 metadata。
  • 反馈状态更新、批量反馈处理、管理员后台反馈列表和组织导出使用同一套公开系统事件转换器,避免处理接口绕过系统事件 metadata 脱敏。
  • 审计日志、AI 失败跟进记录、后台偏好、个人导出和组织导出同样会通过公开转换器隐藏 metadata 或 preferences 中的敏感键;生产环境仍不应把密钥、授权头、Cookie 或第三方凭据写入这些运营字段。
  • 前端渲染从本地存档、云端同步或导入包读取到的 ID、名称、颜色等字段时,应先转义 HTML 属性并清洗 CSS 值;文档/文件夹/执笔人列表已对文档 ID、文件夹 ID、执笔人 ID 和文件夹颜色做边界加固。
  • 云端人工充值收款码 URL 和独立后台支付升级跳转 URL 使用同一套白名单过滤,只允许 HTTP(S) 或相对地址;危险协议和控制字符会回退为未配置占位或拒绝打开。
  • 超过套餐日额度的 AI 调用会在请求模型前原子预留购买额度,成功后才形成消费流水,失败则自动退回;超过 1 小时仍未结算的悬空预留会被恢复,避免并发或进程中断造成永久占款。
  • 导出文件和真实文件夹写入不会直接使用用户标题作为文件名;公共文件名清洗会移除控制字符、折叠空白、清理尾随点号/空格,并处理 Windows 保留设备名。
  • 管理后台导出用量和审计 CSV 时,会把以 =、+、-、@ 或前导空白后的这些字符开头的单元格转为文本,降低电子表格公式注入风险。
  • npm run server:backup 会导出云端逻辑备份。生产环境建议配置 BACKUP_ENCRYPTION_KEY,生成 .json.gcm 加密备份;未配置时仍会生成明文 .json,只适合本地开发或受控灰度环境。
  • npm run server:backup:verify -- <backup-file> 只做只读结构校验,不会恢复或覆盖数据。校验 .json.gcm 需要提供同一 BACKUP_ENCRYPTION_KEY。
  • 对象存储上传默认关闭;启用 BACKUP_OBJECT_STORAGE_MODE=s3-compatible 后,请使用最小权限 access key,并限制为只允许写入备份前缀。
  • 备份失败告警只应包含错误摘要,不应附带备份正文、用户文档或密钥信息。
  • 组织级数据导出只允许 owner/admin 使用,导出内容不包含密码哈希和 API Key 密文。
  • 组织删除/停用当前只创建草案和审计记录,不会立即执行不可逆删除。
  • 过期会话会被清理;过期一段时间的一次性验证码、30 天前登录尝试和 35 天前限流记录也会自动删除。审计、用量、支付和账单记录需另行制定正式保留政策。

什么时候会发送内容到 AI

以下操作可能向你配置的 AI 服务发送内容:

  • AI 起草
  • 段落重写
  • 格式整理
  • 执笔人生成和重训
  • 执笔人测试
  • PPT 内容生成或结构整理

发送内容可能包含:

  • 当前提示词
  • 选中的文档片段
  • 训练样本摘要
  • 执笔人规则
  • 当前编辑区正文

如果材料包含姓名、手机号、证件号、内部安排、未公开政策或其他敏感内容,请先脱敏,或使用符合单位要求的私有模型服务。

执笔人样本安全

执笔人生成会从样本中提取结构和文风。系统会尽量识别并排除:

  • 具体人名
  • 具体日期
  • 具体地点
  • 活动名称
  • 临时安排
  • 一次性政策
  • 不应复用的个案信息

这只是辅助机制,不等于合规审查。导出和分享执笔人包前,请人工检查其中的说明、规则和样本摘要。

训练样本送入 AI 生成执笔人前,以及导出执笔人包前,工作台会在本地扫描手机号、邮箱、身份证号、具体日期、疑似地址/地点和疑似密钥。扫描命中时会提示用户确认,并对提示中的敏感样例做遮罩。该扫描只用于降低误操作风险,不能替代正式脱敏审查。

导入第三方执笔人包时,工作台会先展示包内容预览,包括名称、调用名、分类、版本数、规则摘要、样本摘要和疑似敏感字段提示。若调用名与现有执笔人冲突,用户需要选择覆盖、另存或取消。即便如此,也只应导入来源可信的包。

文件导入风险

当前导入功能在浏览器中解析文件,重点支持 .txt、.md、.csv、.docx 和 .pptx。

.docx 和 .pptx 在解压前会检查 ZIP 条目数、声明总大小和关键 XML 单项大小,拒绝异常压缩包;这只能降低资源耗尽风险,不能证明文件来源可信。

建议:

  • 不导入来源不明的文件。
  • 老式 .doc、.ppt 先用可信办公软件转换为新格式。
  • 不把含宏文件当作普通资料传播。
  • 发现解析异常时,不要反复上传敏感原件到不可信 AI 服务。

导入导出与备份

工作台支持导出备份和执笔人包。导出文件可能包含业务文档、生成内容和写作规则。

工作区备份 v2 不包含本机 API Key 和云端登录态;恢复备份只替换本机文档、标签、类型、设置和执笔人,不覆盖云端数据。备份正文仍可能包含敏感材料,应加密保存并控制分享范围。

分享前请确认:

  • 不包含真实个人信息。
  • 不包含内部制度、账号、链接或密钥。
  • 不包含不应外传的样本文档摘要。
  • 接收方了解执笔人包的适用范围和限制。

云端模式还提供 server:backup 逻辑备份脚本。备份内容可能包含用户邮箱、文档正文、执笔人规则、审计日志和邮件投递记录,不应提交到仓库或发给无权限人员。启用加密备份后,请把 BACKUP_ENCRYPTION_KEY 与备份文件分开保存;如果密钥丢失,加密备份无法校验或恢复。

组织级导出同样可能包含团队文档、反馈和审计记录。共享前请确认导出文件的接收方具备组织管理权限。

依赖安全

项目依赖包括:

  • mammoth
  • jszip
  • pptxgenjs
  • esbuild
  • @playwright/test

建议定期运行:

npm audit

如果修复依赖会影响打包或导入导出逻辑,请同时运行完整测试。

2026-10-15 发布检查

锁文件依赖审计报告 3 项中等级告警,无高危或严重级告警。三项均来自 mammoth → argparse → sprintf-js 依赖链,其中 sprintf-js 的精度参数可能导致资源耗尽(GHSA-hp3w-g68c-fv3c)。

当前检索发现 argparse 由 Mammoth 命令行入口引用,未在其库代码、浏览器构建或本项目打包后的前端中发现对应引用。这限定了当前页面的可达路径,但不代表依赖或安装包完全无风险:安装包仍包含生产依赖,不应额外使用该命令行处理不可信输入。

本次检查时 npm 上 sprintf-js 最新版本仍为 1.1.3,自动修复建议会将 Mammoth 大幅降级到 0.3.29,可能破坏 Word 导入,因此未执行强制降级。后续需跟踪上游修复,并在调整后重跑 Word/PPT 导入、构建与安装回归。

报告安全问题

如果你发现安全或隐私问题,请在公开 Issue 中只描述影响范围和复现方向,不要贴真实数据、API Key 或内部文档。

如果需要提供样本,请先构造脱敏示例。

There aren't any published security advisories