# 安全政策 中文 | [English](docs/SECURITY.en.md) | [日本語](docs/SECURITY.ja.md) | [偽中国語](docs/SECURITY.pcn.md) ## 支持的版本 本项目以 flake 形式分发,**只有最新的 `main` 分支**接受安全修复。 历史提交不单独维护——如需旧版本,请自行 fork 并自行承担维护。 | 范围 | 支持 | |------|------| | `main` 分支(最新) | ✅ 接受安全修复 | | 已发布的 flake 输出(旧代际) | ❌ 请升级到最新 | | `dsh-api-balance` 子项目 | 该子项目**已自建安全政策**(含已评估报告清单与设计边界)——漏洞请报至其[独立仓库的私有报告渠道](https://github.com/Kihara777/dsh-api-balance/security/advisories/new),或参阅 [`SECURITY.md`](https://github.com/Kihara777/dsh-api-balance/blob/main/SECURITY.md) | ## 报告漏洞 **请不要用公开 issue 报告安全问题。** 请任选一种私下渠道: 1. **GitHub 私有漏洞报告**(推荐): 2. 邮件:`npm@g41.moe` 请在报告中尽量包含: - 受影响的组件(包 / 模块 / 技能 / 插件)与文件路径 - 复现步骤或概念验证 - 影响评估(能否读取数据、执行代码、提权、拒绝服务) - 若有修复建议,一并说明 ## 响应时限 本项目由个人维护,且维护者持有**一级视力残疾**证明, 处理速度可能受身体状况影响——请谅解这一现实约束。 | 阶段 | 目标时限 | |------|---------| | 确认收到 | 7 天内 | | 初步评估 | 14 天内 | | 修复或缓解 | 视严重程度与身体状况而定,会保持沟通 | 严重问题会优先处理。若长时间未获回应,可再发一次邮件提醒。 ## 已知的设计边界 以下**不是**漏洞,而是有意为之的行为,报告前请先确认: | 项 | 说明 | |---|---| | `nixkits.dsh.reverseProxy.autoAuth` | 声明式**免认证入口**,仅应启用于可信局域网;风险由使用者的网络边界承担(见 `docs/zh/dsh.md`) | | `sudo` 守护进程 | 需 root 的操作经外部 sudo 守护进程执行并留痕;沙箱权限档位由使用者在会话中显式选择,**默认不放开** | | `dsh-api-balance` 读取浏览器 Local Storage | 用于提取平台会话令牌,**默认开启且可关闭**;仅读取令牌,不采集浏览器内其他数据,令牌以 `0600` 落盘 | | `/nix/store` 绝对路径 | 配置中硬编码 store 路径会在 GC 后失效——属已知陷阱而非漏洞,仓库提供 `nixos_cli op=audit-store-paths` 审计 | ## 已评估的外部报告(含关闭项) 以下报告均已经**逐条复核**并公开回复证据。**列出它们是为了让后续报告者不必重复提交同类问题**—— 若你认为某条结论有误,欢迎指出,我们会重新评估。 | 编号 | 报告内容 | 结论 | 依据 | |------|---------|------|------| | PR #4(@anupamme) | 称 `/token`、`/voicepack`、`/tts` 缺少限流 | **误报,未合并** | 描述与 diff 不符(实际只改了 `/query`);其限流键 `x-forwarded-for` 客户端可伪造,且本机同源 RPC 不带该头,会把全部本机流量并入单一桶而误伤自己 | | PR #5(@anupamme) | 称 `/query` 缺少请求体体积上限 | **误报,未合并** | 该防护早已由 `readJsonBody` 的 64 KiB 上限提供;其新增的 `content-length` 检查可被 chunked 绕过,`text.length` 又是 UTF-16 码元数而非字节数 | | issue #1(@begininvoke) | 称 `secrets: inherit` 违反最小权限 | **误报,已关闭** | 被调方是本仓库内的本地 workflow(非 issue 假设的外部来源);全仓仅 2 个 secret,显式传递与 `inherit` 集合完全相同,对攻击者零增益 | | issue #2(@begininvoke) | 同 issue #1(内容逐字节重复) | **重复,已关闭** | 同上 | > 这四条报告**规则命中本身大多属实**,但威胁模型不适用于本项目的部署形态。 > 我们按「先复核、再答复、附可复现证据」处理,而非直接照单接受。 ### 关于重复提交 **上表已列出的同一结论,若再次提交且未提供新证据,将直接关闭并指向本节。** 这不是拒绝安全报告,而是划分界限: | 会被受理 | 会被直接关闭 | |---------|-------------| | 上表未涵盖的**新**问题 | 与上表同一结论、且无新证据的重复报告 | | 指出上表某条结论**有误**,并附可复现证据 | 仅重述上表已有结论 | | 相同主题但有**不同的**威胁模型或可利用路径 | 同一规则的再次自动扫描输出 | **「指出结论有误」始终欢迎**——上表四条亦是经复核后作出的判断,若判据本身错了,我们改正。 ### 它们带来的真实改进 这些报告**促成了两次真实的加固**——虽然报告本身是误报,但其指向的方向值得追查: | 加固 | 内容 | |------|------| | **`/tts` 端点 SSRF** | 报告未提及,但复核端点时发现:该代理接受任意 `http(s)` URL 并以 host 身份请求,且原样转发用户可控的 `headers`。已修复——拒绝回环 / 私有 / 链路本地 / 保留地址(含 IPv4-mapped IPv6),自定义请求头改为白名单。**该端点已随 `dsh-api-balance` 迁至[独立仓库](https://github.com/Kihara777/dsh-api-balance)** | | **CI 最小权限** | 复核 issue 时发现:31 个构建 workflow 未声明 `permissions`,因而继承仓库默认(可能为读写),而它们只需 `contents: read`。已全部补上 | **含义**:本仓库欢迎报告,也会认真复核;误报不会被视为打扰——上表四条报告最终引出了两次真实加固。 ## 供应链说明 - 本仓库的 CI 将第三方 GitHub Actions **固定到提交 SHA**(非浮动标签) - 仓库**不含**任何密钥;凭据一律置于仓库之外并经 `path:` input 引入 - 构建产物推送到公开的 Cachix 二进制缓存 - 构建 workflow 显式声明最小权限(`contents: read`) ## 致谢 负责任地披露漏洞的报告者,若愿意,将在修复记录(`MAINTENANCE.md`)中具名致谢。