diff --git a/.hermes/plans/2026-05-11_205658-security-vulnerability-scan.md b/.hermes/plans/2026-05-11_205658-security-vulnerability-scan.md new file mode 100644 index 00000000..fd17c42e --- /dev/null +++ b/.hermes/plans/2026-05-11_205658-security-vulnerability-scan.md @@ -0,0 +1,403 @@ +# 当前项目安全漏洞检查计划 + +> **For Hermes:** Use subagent-driven-development skill only if the user later asks to execute this plan. 本计划当前仅用于规划,不实施代码修改。 + +**Goal:** 对 Genarrative 当前工作区做一次可复现的安全漏洞基线检查,覆盖依赖漏洞、密钥泄露、常见高风险代码模式、后端 Rust crate 风险和前端/Node 供应链风险,并输出可落地的整改清单。 + +**Architecture:** 采用“只读扫描 → 结果归档 → 人工分级 → 最小修复建议”的方式推进。先不直接升级依赖或改代码,避免安全扫描引入不可控 breaking change;执行阶段只在用户确认后运行扫描命令,并把报告保存到 `docs/audits/` 或 `.hermes/plans/` 附件中。 + +**Tech Stack:** Node/Vite/React/TypeScript、Rust workspace/Axum/SpacetimeDB、npm lockfile、Cargo.lock、Git worktree。 + +--- + +## 当前上下文 / 假设 + +- 当前有效工作区:`C:/proj/Genarrative/.worktrees/hermes-3337436a`。 +- 本次用户以 `/plan` 模式要求“检查一下当前项目的安全漏洞”,因此本轮只制定计划,不执行会产生报告、安装工具、修改依赖、提交或推送的操作。 +- 已确认项目包含: + - 根 `package.json`,脚本包括 `npm run lint`、`npm run test`、`npm run build`、`npm run check:encoding`。 + - 根 `package-lock.json`。 + - `server-rs/Cargo.toml` 和 `server-rs/Cargo.lock`。 + - `apps/admin-web/package.json`、`packages/shared/package.json`。 +- `.hermes/shared-memory/development-workflow.md` 要求开发前读取共享记忆,并以当前代码、`docs/`、`AGENTS.md` 为准。 +- 安全扫描不应把真实密钥写入仓库;发现疑似密钥时只记录文件位置、变量名、脱敏片段和处置建议。 + +## 总体策略 + +1. 先做仓库状态和范围确认,避免扫描其他 worktree 或错误路径。 +2. 优先运行不会修改文件的安全检查:`npm audit --json`、`cargo audit`、密钥扫描、危险代码模式扫描。 +3. 分前端供应链、后端供应链、源码安全、配置/脚本安全四类归档。 +4. 对结果按严重级别分层:Critical / High / Medium / Low / Informational。 +5. 对每个真实问题给出:影响范围、证据、可行修复、验证命令、是否需要业务回归。 +6. 只有在用户确认进入执行/修复阶段后,才做依赖升级、代码修复、文档更新、测试和提交。 + +--- + +## Step-by-step Plan + +### Task 1: 确认扫描工作区和基线状态 + +**Objective:** 确保后续扫描针对当前 worktree,且不会误把既有未提交变更当成安全修复结果。 + +**Files:** +- Read-only: `AGENTS.md` +- Read-only: `.hermes/README.md` +- Read-only: `.hermes/shared-memory/development-workflow.md` +- Read-only: `package.json` +- Read-only: `server-rs/Cargo.toml` + +**Commands:** + +```bash +pwd +git status --short +git branch --show-current +git rev-parse --show-toplevel +``` + +**Expected:** +- `pwd` / `git rev-parse --show-toplevel` 指向 `C:/proj/Genarrative/.worktrees/hermes-3337436a` 对应路径。 +- 分支为当前隔离 worktree 分支。 +- 记录是否已有未提交变更;如存在,扫描报告需标注“基于含未提交变更的工作区”。 + +**Validation:** +- 不修改任何项目文件。 +- 如发现路径不是当前 worktree,停止并重新确认路径。 + +### Task 2: 生成依赖清单和锁文件基线 + +**Objective:** 明确 Node 与 Rust 依赖入口,避免漏扫子包或 admin web。 + +**Files:** +- Read-only: `package.json` +- Read-only: `package-lock.json` +- Read-only: `apps/admin-web/package.json` +- Read-only: `packages/shared/package.json` +- Read-only: `server-rs/Cargo.toml` +- Read-only: `server-rs/Cargo.lock` + +**Commands:** + +```bash +npm --version +node --version +cargo --version +rustc --version +``` + +可选只读清单: + +```bash +npm ls --all --json > /tmp/genarrative-npm-ls.json +cargo metadata --manifest-path server-rs/Cargo.toml --format-version 1 > /tmp/genarrative-cargo-metadata.json +``` + +**Expected:** +- 明确 npm / Node / Rust / Cargo 版本。 +- 若 `npm ls` 因 peer dependency 或历史依赖问题非 0,保留输出并继续 audit。 + +**Validation:** +- `/tmp` 输出不进入 Git。 +- 不运行 `npm install`、`npm update`、`cargo update`。 + +### Task 3: Node 供应链漏洞扫描 + +**Objective:** 检查根 lockfile 覆盖的前端、脚本和 admin web 依赖漏洞。 + +**Files:** +- Read-only: `package-lock.json` +- Read-only: `package.json` + +**Commands:** + +```bash +npm audit --json > /tmp/genarrative-npm-audit.json +npm audit --audit-level=moderate +``` + +**Expected:** +- `npm audit --json` 生成机器可读结果。 +- 第二条命令给出人类可读摘要;如返回非 0,按漏洞严重度记录,不直接执行 `npm audit fix`。 + +**Result fields to extract:** +- package name +- vulnerable versions +- installed version +- severity +- CVE / GHSA +- via chain +- fixAvailable 是否为 major/breaking +- affected direct dependency or transitive dependency + +**Validation:** +- 不执行 `npm audit fix`。 +- 如 npm registry 网络不可用,记录阻塞原因和可重试命令。 + +### Task 4: Rust 供应链漏洞扫描 + +**Objective:** 检查 `server-rs` workspace 的 Cargo 依赖漏洞、弃用 crate 和 yanked crate。 + +**Files:** +- Read-only: `server-rs/Cargo.toml` +- Read-only: `server-rs/Cargo.lock` + +**Commands:** + +优先: + +```bash +cargo audit --json --manifest-path server-rs/Cargo.toml > /tmp/genarrative-cargo-audit.json +cargo audit --manifest-path server-rs/Cargo.toml +``` + +如果本机没有 `cargo audit`: + +```bash +cargo install cargo-audit --locked +cargo audit --manifest-path server-rs/Cargo.toml +``` + +**Execution note:** +- 安装 `cargo-audit` 会改变用户 Cargo 工具目录,不属于纯只读扫描;执行前需用户确认。 +- 如果用户不希望安装工具,则记录“Rust 漏洞扫描未完成”,并给出本地安装或 CI 执行建议。 + +**Result fields to extract:** +- advisory id +- package +- version +- patched versions +- unaffected versions +- severity / CVSS if available +- dependency path +- whether it is runtime reachable in `api-server` / `spacetime-module` + +**Validation:** +- 不运行 `cargo update`。 +- 不改 `Cargo.lock`。 + +### Task 5: 密钥和敏感配置泄露扫描 + +**Objective:** 检查仓库中是否误提交 API key、token、私钥、cookie、`.env` 类文件或个人 Hermes 配置。 + +**Files / paths to scan:** +- Full repo excluding `.git/`, `node_modules/`, `target/`, `dist/`, build artifacts。 +- 特别关注:`.hermes/`、`scripts/`、`server-rs/`、`apps/admin-web/`、`src/`、`docs/`。 + +**Preferred commands:** + +如果有 gitleaks: + +```bash +gitleaks detect --source . --no-git --redact --report-format json --report-path /tmp/genarrative-gitleaks.json +``` + +如果没有 gitleaks,先用只读 grep/ripgrep 兜底: + +```bash +git ls-files -z | xargs -0 grep -nIE "(api[_-]?key|secret|password|passwd|token|private[_-]?key|BEGIN (RSA|OPENSSH|EC|DSA)? ?PRIVATE KEY|AKIA[0-9A-Z]{16}|xox[baprs]-|sk-[A-Za-z0-9_-]{20,})" > /tmp/genarrative-secret-grep.txt || true +``` + +**Execution note:** +- 安装 gitleaks 需要用户确认。 +- grep 结果包含 false positive,必须人工分级,不得直接当作泄露结论。 + +**Validation:** +- 报告中对值做脱敏,只保留前后 3-4 位或完全不记录值。 +- 如果发现 `.env.local` 或真实 token 被跟踪,立即标为 Critical。 + +### Task 6: 常见源码安全模式扫描 + +**Objective:** 快速发现高风险代码模式:命令注入、动态执行、路径穿越、危险反序列化、XSS、日志泄密、宽松 CORS 等。 + +**Files / paths:** +- `src/**/*.{ts,tsx,js,mjs,cjs}` +- `apps/admin-web/**/*.{ts,tsx,js,mjs,cjs}` +- `scripts/**/*.{js,mjs,cjs,ts}` +- `server-rs/crates/**/*.rs` + +**Commands:** + +```bash +# JS/TS 动态执行与 HTML 注入 +rg -n "\beval\(|new Function\(|dangerouslySetInnerHTML|innerHTML\s*=|document\.write\(" src apps scripts packages + +# Node 命令执行风险 +rg -n "exec\(|execSync\(|spawn\(|spawnSync\(|shell:\s*true|child_process" scripts src apps packages + +# Rust 命令、文件路径、unwrap 风险热点 +rg -n "Command::new|std::process|\.unwrap\(|\.expect\(|fs::|File::open|PathBuf|set_header|cors|CorsLayer" server-rs/crates + +# 宽松 CORS / Cookie / Auth 相关热点 +rg -n "allow_origin|Any|cookie|Authorization|Bearer|refresh|access_token|set_cookie|SameSite|Secure|HttpOnly" server-rs/crates src apps scripts +``` + +**Expected:** +- 输出作为“热点清单”,不等同于漏洞。 +- 对 auth/session、文件上传、OSS 签名、外部 LLM/图片服务请求、SpacetimeDB 访问 facade 做人工复核。 + +**Validation:** +- 每个疑似问题必须能说明可利用条件,无法说明则降级为 Informational。 + +### Task 7: Web/API 安全配置人工复核 + +**Objective:** 对项目特有的安全边界做代码审阅,补足工具扫描无法覆盖的业务风险。 + +**Likely files to review:** +- `server-rs/crates/api-server/src/**` +- `server-rs/crates/platform-auth/src/**` +- `server-rs/crates/platform-oss/src/**` +- `server-rs/crates/platform-llm/src/**` +- `server-rs/crates/spacetime-client/src/**` +- `src/services/**` +- `apps/admin-web/src/**` +- `scripts/*deploy*` +- `scripts/*api-server*` +- `.github/workflows/**` if present + +**Checklist:** +- Auth / session:access token 与 refresh cookie 的生命周期、SameSite/Secure/HttpOnly、错误日志是否泄露 token。 +- CORS:开发环境与生产环境是否区分,是否存在生产 `Any`。 +- SSRF / outbound:LLM、图片生成、OSS、任意 URL 下载是否校验协议和大小。 +- Upload / Data URL:大小限制、MIME 校验、base64 解析错误处理。 +- Path traversal:脚本和后端是否拼接用户输入路径。 +- Admin:后台接口是否有权限校验,是否复用普通用户 token。 +- SpacetimeDB:private table / reducer 是否绕过 api-server facade 暴露敏感数据。 +- Logging:日志是否打印 API key、token、cookie、用户私密内容。 + +**Validation:** +- 对每个命中的真实风险,记录具体文件路径和函数名。 +- 对“需要运行环境才能验证”的风险,列出 smoke 或单测建议。 + +### Task 8: 汇总漏洞分级与整改建议 + +**Objective:** 把扫描结果转成团队可执行的安全整改报告。 + +**Deliverable candidates:** +- `docs/audits/SECURITY_VULNERABILITY_SCAN_YYYY-MM-DD.md` +- 或如果用户只要临时报告:`.hermes/plans/assets/security-scan-YYYY-MM-DD.md` + +**Report structure:** + +```markdown +# 安全漏洞扫描报告 YYYY-MM-DD + +## 扫描范围 +## 扫描命令与环境 +## 摘要 +## Critical +## High +## Medium +## Low +## Informational / False Positive +## 依赖升级建议 +## 代码修复建议 +## 需要人工确认的问题 +## 验证命令 +``` + +**Validation:** +- 报告不包含真实密钥。 +- 每条问题都有“证据、影响、建议、验证”。 +- 明确哪些是工具扫描结果,哪些是人工判断。 + +### Task 9: 如用户要求修复,再分批执行最小修复 + +**Objective:** 避免一次性大规模升级导致回归,把修复拆为可验证的小批次。 + +**Suggested order:** +1. Critical secrets:立即移除、轮换密钥、补 `.gitignore`/文档约束(注意项目约束:不要在 `.gitignore` 中添加 `.env.local`)。 +2. Critical/High direct dependencies:优先升级 direct dependency,运行最小测试。 +3. Critical/High transitive dependencies:评估是否由 direct dependency patch/minor 升级带出。 +4. 源码漏洞:按入口编写回归测试,再修复。 +5. Medium/Low:按风险和 breaking change 代价排期。 + +**Required verification after fixes:** + +```bash +npm run check:encoding +npm run lint:eslint +npm run typecheck +npm run test +npm run build +cd server-rs && cargo test --workspace +``` + +后端 API 或 auth 修复涉及运行态时,还需要: + +```bash +npm run api-server +# 另一个终端检查 /healthz 并执行对应 smoke +``` + +**Validation:** +- 修复后重新跑对应 audit / secret scan。 +- 走 `requesting-code-review` 的独立安全复核流程。 + +--- + +## Files likely to change(仅修复阶段) + +本计划阶段不修改以下文件;只有用户确认执行修复时才可能变化: + +- `package.json` +- `package-lock.json` +- `apps/admin-web/package.json` +- `server-rs/Cargo.toml` +- `server-rs/Cargo.lock` +- `server-rs/crates/api-server/src/**` +- `server-rs/crates/platform-auth/src/**` +- `server-rs/crates/platform-oss/src/**` +- `server-rs/crates/platform-llm/src/**` +- `src/services/**` +- `apps/admin-web/src/**` +- `scripts/**` +- `docs/audits/SECURITY_VULNERABILITY_SCAN_YYYY-MM-DD.md` +- `.hermes/shared-memory/pitfalls.md`(仅当发现长期有效、会反复踩的安全排障经验时更新) + +## Tests / Validation + +安全扫描执行阶段: + +```bash +npm audit --json > /tmp/genarrative-npm-audit.json +npm audit --audit-level=moderate +cargo audit --manifest-path server-rs/Cargo.toml +rg -n "\beval\(|new Function\(|dangerouslySetInnerHTML|innerHTML\s*=|document\.write\(" src apps scripts packages +rg -n "exec\(|execSync\(|spawn\(|spawnSync\(|shell:\s*true|child_process" scripts src apps packages +rg -n "Command::new|std::process|\.unwrap\(|\.expect\(|fs::|File::open|PathBuf|set_header|cors|CorsLayer" server-rs/crates +``` + +修复执行阶段: + +```bash +npm run check:encoding +npm run lint:eslint +npm run typecheck +npm run test +npm run build +cd server-rs && cargo test --workspace +``` + +如变更后端运行态、安全中间件、auth/session: + +```bash +npm run api-server +# 检查 /healthz +# 执行相关 auth / API smoke +``` + +## Risks, tradeoffs, and open questions + +- `npm audit fix` 可能升级 major version,破坏 Vite/React/ESLint/Vitest 兼容性;必须先人工审查 `fixAvailable`。 +- `cargo audit` 可能需要安装 `cargo-audit`;安装工具属于用户环境变更,应先确认。 +- 密钥扫描极易产生 false positive;必须人工复核,报告中禁止输出真实密钥。 +- Rust `unwrap/expect` 不是天然漏洞;只有对外部输入、网络、文件、数据库响应等不可信数据造成 panic/DoS 时才升级为真实风险。 +- Web 安全检查需要区分开发环境和生产环境;开发 CORS 放宽不等于生产漏洞,但生产配置必须有明确边界。 +- 如果扫描发现历史提交中曾泄露密钥,删除当前文件不够,必须轮换密钥并考虑历史清理策略。 +- 当前计划未直接访问 CI/Jenkins/生产配置;若用户希望覆盖 CI/CD、镜像、部署主机和运行时端口,需要补充 Jenkins console、部署脚本和生产环境配置的只读访问方式。 + +## Missing artifacts / follow-up checkpoints + +- 尚未获得用户确认是否允许安装 `cargo-audit` / `gitleaks` 等工具。 +- 尚未执行真实扫描,因此当前没有漏洞结论;执行后需要生成正式报告。 +- 如果用户希望“检查当前项目”包含远端仓库历史 secrets、Docker 镜像、Jenkins 凭据和生产运行时配置,需要另行确认访问范围和凭据边界。 diff --git a/docs/audits/SECURITY_VULNERABILITY_SCAN_2026-05-11.md b/docs/audits/SECURITY_VULNERABILITY_SCAN_2026-05-11.md new file mode 100644 index 00000000..11e7f2f0 --- /dev/null +++ b/docs/audits/SECURITY_VULNERABILITY_SCAN_2026-05-11.md @@ -0,0 +1,377 @@ +# 安全漏洞扫描报告 2026-05-11 + +## 扫描范围 + +- 工作区:`C:/proj/Genarrative/.worktrees/hermes-3337436a` +- 分支:`hermes/hermes-3337436a` +- Git 基线:扫描时存在一个未跟踪计划文件 `.hermes/plans/2026-05-11_205658-security-vulnerability-scan.md`。 +- 扫描对象:根 Node/Vite/React 依赖、`server-rs` Rust workspace 依赖入口、仓库已跟踪文件中的敏感配置、JS/TS/Rust 源码安全热点。 + +## 扫描命令与工具状态 + +已执行: + +```bash +pwd +git branch --show-current +git rev-parse --show-toplevel +git status --short +node --version +npm --version +cargo --version +rustc --version +rg --version +npm audit --json +npm audit --audit-level=moderate +git ls-files -z | xargs -0 grep -nIE "(api[_-]?key|secret|password|passwd|token|private[_-]?key|BEGIN (RSA|OPENSSH|EC|DSA)? ?PRIVATE KEY|AKIA[0-9A-Z]{16}|xox[baprs]-|sk-[A-Za-z0-9_-]{20,})" +rg -n "\beval\(|new Function\(|dangerouslySetInnerHTML|innerHTML\s*=|document\.write\(" src apps scripts packages +rg -n "exec\(|execSync\(|spawn\(|spawnSync\(|shell:\s*true|child_process" scripts src apps packages +rg -n "Command::new|std::process|\.unwrap\(|\.expect\(|fs::|File::open|PathBuf|set_header|cors|CorsLayer" server-rs/crates +rg -n "allow_origin|Any|cookie|Authorization|Bearer|refresh|access_token|set_cookie|SameSite|Secure|HttpOnly" server-rs/crates src apps scripts +``` + +工具版本: + +- Node:`v22.22.2` +- npm:`10.9.7` +- Cargo:`cargo 1.95.0 (f2d3ce0bd 2026-03-21)` +- Rustc:`rustc 1.95.0 (59807616e 2026-04-14)` +- ripgrep:`15.1.0` +- `gitleaks`:未安装,本次未执行。 +- `cargo-audit`:未安装,本次未执行;未擅自安装到用户环境。 + +原始扫描输出保存于: + +- `.hermes/plans/assets/security-scan-2026-05-11/npm-audit.json` +- `.hermes/plans/assets/security-scan-2026-05-11/npm-audit.txt` +- `.hermes/plans/assets/security-scan-2026-05-11/secret-grep.txt` +- `.hermes/plans/assets/security-scan-2026-05-11/js-xss-dynamic.txt` +- `.hermes/plans/assets/security-scan-2026-05-11/node-command-exec.txt` +- `.hermes/plans/assets/security-scan-2026-05-11/rust-hotspots.txt` +- `.hermes/plans/assets/security-scan-2026-05-11/auth-cors-hotspots.txt` + +注意:`secret-grep.txt` 可能包含敏感片段,提交前应删除或改为脱敏摘要,不建议直接进入 Git。 + +## 摘要 + +| 等级 | 数量 | 说明 | +| --- | ---: | --- | +| Critical | 1 | `.env.local` 被 Git 跟踪且含多项非空真实密钥/凭据形态配置。 | +| High | 2 | npm 依赖存在 8 个 high advisory 聚合项;Vite dev server 任意文件读取类漏洞需要优先升级。另有 TypeScript ESLint 链路 ReDoS 风险。 | +| Medium | 2 | esbuild dev server 请求读取、PostCSS CSS stringify XSS。 | +| Low | 3 | jsdom/http-proxy-agent/@tootallnate/once 低危链路。 | +| Unknown | 1 | Rust 依赖漏洞未完成扫描,因为本机未安装 `cargo-audit`。 | +| Informational | 多项 | 源码热点扫描命中大量测试/脚本/unwrap/expect,需要按入口人工复核。 | + +## Critical + +### C-1:仓库跟踪了 `.env.local`,且包含多项非空真实密钥形态配置 + +**证据:** + +`git ls-files --error-unmatch .env.local` 显示 `.env.local` 已被 Git 跟踪。扫描确认该文件包含多项非空密钥/凭据形态变量,包括但不限于: + +- `LLM_API_KEY` +- `ARK_API_KEY` +- `ARK_CHARACTER_VIDEO_API_KEY` +- `DASHSCOPE_API_KEY` +- `VOLCENGINE_ACCESS_KEY_ID` +- `VOLCENGINE_SECRET_ACCESS_KEY` +- `ALIYUN_SMS_ACCESS_KEY_ID` +- `ALIYUN_SMS_ACCESS_KEY_SECRET` +- `GENARRATIVE_LLM_API_KEY` +- `ALIYUN_OSS_ACCESS_KEY_ID` +- `ALIYUN_OSS_ACCESS_KEY_SECRET` +- `GENARRATIVE_ADMIN_PASSWORD` + +报告中不记录具体值。 + +**影响:** + +如果该文件已进入远端仓库或被团队成员拉取,相关外部服务密钥、OSS/SMS/LLM/后台密码均应视为已泄露。即使后续从当前工作树删除,也不能撤销历史泄露风险。 + +**建议修复:** + +1. 立即轮换 `.env.local` 中出现过的所有真实密钥、访问密钥、后台密码和 token。 +2. 从 Git 跟踪中移除 `.env.local`,但不要删除本地私有文件: + + ```bash + git rm --cached .env.local + ``` + +3. 按项目约束,不要在 `.gitignore` 中新增 `.env.local`;如果仓库已有其他机制管理本地私密 env,应遵循既有约定。若没有,应先补一份安全说明文档,而不是提交真实 `.env.local`。 +4. 将必要的占位示例保留在 `.env.example` 或 `deploy/env/api-server.env.example`,确保示例值不是可用密钥。 +5. 如该文件已推送到远端历史,评估是否需要历史清理;无论是否清历史,密钥轮换都是必须步骤。 + +**验证:** + +```bash +git ls-files --error-unmatch .env.local +# 预期:返回非 0,表示不再跟踪 + +git diff --cached -- .env.local +# 预期:只显示从索引移除,不输出真实值到公开报告 +``` + +## High + +### H-1:Vite 依赖存在高危 dev server 任意文件读取/路径遍历类 advisory + +**证据:** + +`npm audit` 显示: + +- package:`vite` +- direct dependency:是 +- installed vulnerable range:`<=6.4.1` +- severity:`high` +- 相关 advisory 包括: + - `GHSA-p9ff-h696-f583`:Vite dev server WebSocket 任意文件读取,高危。 + - `GHSA-4w7w-66w2-5vf9`:optimized deps `.map` 处理路径遍历,中危。 + - 多个 `server.fs` / public directory 相关低中危问题。 +- `fixAvailable=true`。 + +**影响:** + +主要影响开发服务器和预览环境。如果开发机、测试机或内网联调环境将 Vite dev server 暴露给不可信网络,攻击者可能读取工作区文件或旁路 `server.fs` 限制。 + +**建议修复:** + +1. 优先将 `vite` 升级到 npm audit 推荐的安全版本范围。 +2. 升级后执行: + + ```bash + npm run check:encoding + npm run lint:eslint + npm run typecheck + npm run test + npm run build + ``` + +3. 检查 `scripts/vite-cli.mjs`、`scripts/dev-web-rust.mjs`、Vite 配置中的 dev server host 暴露范围,开发环境避免绑定 `0.0.0.0` 或暴露到公网。 + +### H-2:`@typescript-eslint/*` 链路经 `minimatch` 存在 ReDoS 高危 advisory + +**证据:** + +`npm audit` 显示: + +- direct packages: + - `@typescript-eslint/eslint-plugin`,当前范围 `6.16.0 - 7.5.0`,high。 + - `@typescript-eslint/parser`,当前范围 `6.16.0 - 7.5.0`,high。 +- transitive packages: + - `@typescript-eslint/type-utils` + - `@typescript-eslint/typescript-estree` + - `@typescript-eslint/utils` + - `minimatch` +- `minimatch` advisory: + - `GHSA-3ppc-4f35-3m26` + - `GHSA-7r86-cg39-jmmj` + - `GHSA-23c5-xmqv-rm74` +- npm 建议升级到 `@typescript-eslint/* 8.59.3`,属于 SemVer major。 + +**影响:** + +主要影响 lint/构建工具链。如果 CI 或开发命令处理不可信 glob pattern,可能造成 ReDoS。生产运行时直接影响较低,但 CI 可用性和供应链安全仍应修复。 + +**建议修复:** + +1. 单独开依赖升级分支,将 `@typescript-eslint/eslint-plugin` 与 `@typescript-eslint/parser` 升级到兼容 ESLint 8/TypeScript 5.8 的安全版本。 +2. 因为是 major 升级,先阅读迁移说明并运行 ESLint 全量检查。 +3. 验证: + + ```bash + npm run lint:eslint + npm run typecheck + npm run test + ``` + +### H-3:`picomatch` ReDoS / glob matching 高危 advisory + +**证据:** + +`npm audit` 显示: + +- package:`picomatch` +- severity:`high` +- vulnerable range:`4.0.0 - 4.0.3` +- advisory: + - `GHSA-c2c7-rcm5-vvqj`:extglob quantifiers ReDoS,高危。 + - `GHSA-3v7f-55p6-f55p`:POSIX character classes method injection,中危。 +- `fixAvailable=true`。 + +**影响:** + +主要影响依赖 picomatch 的构建、测试、文件匹配工具链。生产直接影响取决于是否在服务端运行时用它处理用户输入 glob;当前未在扫描摘要中发现明显业务入口直接使用。 + +**建议修复:** + +通过升级引入它的 direct dependency 来消除,不建议手工改 lockfile。 + +## Medium + +### M-1:`esbuild <=0.24.2` dev server 允许任意网站请求并读取响应 + +**证据:** + +`npm audit` 显示: + +- package:`esbuild` +- severity:`moderate` +- advisory:`GHSA-67mh-4wv8-2f99` +- vulnerable range:`<=0.24.2` +- `fixAvailable=true`。 + +**影响:** + +主要影响开发服务器场景。若本地开发服务暴露到不可信网络,风险上升。 + +**建议修复:** + +随 Vite / 构建链路升级一并修复,升级后跑前端检查与构建。 + +### M-2:`postcss <8.5.10` CSS stringify XSS advisory + +**证据:** + +`npm audit` 显示: + +- package:`postcss` +- severity:`moderate` +- advisory:`GHSA-qx2v-qp2m-jg93` +- vulnerable range:`<8.5.10` +- `fixAvailable=true`。 + +**影响:** + +如果系统把不可信 CSS 内容 stringify 后注入页面,可能触发 XSS。当前项目是否存在这类业务入口需人工复核;从依赖角度建议升级。 + +**建议修复:** + +升级 Tailwind/Vite/PostCSS 链路带出的安全版本,并执行前端构建验证。 + +## Low + +### L-1:`jsdom` 链路低危 advisory + +**证据:** + +`npm audit` 显示: + +- `jsdom` direct dependency,severity low。 +- transitive:`http-proxy-agent`、`@tootallnate/once`。 +- npm 建议升级到 `jsdom 29.1.1`,SemVer major。 + +**影响:** + +通常影响测试环境。若测试工具处理不可信 URL/代理输入,风险上升。 + +**建议修复:** + +不要和 Vite/TypeScript ESLint 大升级混在一个提交里。单独升级 jsdom 后运行: + +```bash +npm run test +``` + +## Unknown / 未完成项 + +### U-1:Rust 依赖漏洞未完成扫描 + +**原因:** + +本机没有 `cargo-audit`,本次没有擅自安装用户级 Cargo 工具。 + +**建议:** + +如确认允许安装: + +```bash +cargo install cargo-audit --locked +cargo audit --manifest-path server-rs/Cargo.toml +``` + +或在 CI/具备工具的环境执行并回填结果。 + +## Informational / 源码热点 + +### I-1:JS/TS XSS / 动态执行热点 + +扫描命中 1 行: + +- `src/routing/RouteImageReadyGate.test.ts` 中测试代码使用 `root.innerHTML`。 + +初步判断为测试环境构造 DOM,不是生产漏洞。若后续发现生产代码使用 `dangerouslySetInnerHTML` 或直接 `innerHTML = userInput`,应升级为 High。 + +### I-2:Node 脚本命令执行热点 + +扫描命中 21 行,主要集中在: + +- `scripts/spacetime-migration-common.mjs` +- `scripts/run-bash-script.mjs` +- `scripts/generate-spacetime-bindings.mjs` +- `scripts/dev-web-rust.mjs` + +初步判断为项目脚本启动 `spacetime`、bash、Vite 等工具的正常行为。后续人工复核重点: + +- 是否使用固定命令和参数数组,而不是拼接 shell 字符串。 +- 是否把用户输入直接作为命令或 shell 参数。 +- 是否设置 `shell: true`。 + +### I-3:Rust unwrap/expect、文件路径、CORS/Auth 热点较多 + +扫描命中: + +- `rust-hotspots.txt`:1348 行。 +- `auth-cors-hotspots.txt`:1157 行。 + +这些是热点,不等于漏洞。建议后续按模块分批人工复核: + +1. `server-rs/crates/api-server/src/admin.rs` +2. `server-rs/crates/api-server/src/app.rs` +3. `server-rs/crates/platform-auth/src/**` +4. `server-rs/crates/platform-oss/src/**` +5. `server-rs/crates/platform-llm/src/**` +6. `server-rs/crates/spacetime-client/src/**` + +重点看:生产 CORS、Cookie 安全属性、token 日志、路径拼接、外部 URL 下载、Data URL 大小限制、OSS 签名边界。 + +## 推荐修复顺序 + +1. 立即处理 C-1:轮换 `.env.local` 里所有真实密钥,并从 Git 索引移除 `.env.local`。 +2. 升级 `vite` 相关依赖,优先消除 dev server 任意文件读取/路径遍历 advisory。 +3. 升级 `@typescript-eslint/*`,消除 minimatch 链路 ReDoS;因 major 升级,单独提交。 +4. 升级 `postcss` / `esbuild` / `picomatch` 的来源依赖。 +5. 单独评估 `jsdom` major 升级。 +6. 用户确认后安装或使用 CI 执行 `cargo audit`,补齐 Rust 依赖漏洞结论。 +7. 对 `auth-cors-hotspots.txt` 和 `rust-hotspots.txt` 做模块级人工审计。 + +## 修复后的验证命令 + +```bash +npm run check:encoding +npm run lint:eslint +npm run typecheck +npm run test +npm run build +``` + +如修改后端安全、Auth、Cookie、CORS 或 API: + +```bash +cd server-rs && cargo test --workspace +npm run api-server +# 检查 /healthz,并执行相关 API/auth smoke +``` + +如补齐 Rust audit: + +```bash +cargo audit --manifest-path server-rs/Cargo.toml +``` + +## 备注 + +- 本报告没有输出任何真实密钥值。 +- `.hermes/plans/assets/security-scan-2026-05-11/secret-grep.txt` 可能包含敏感内容,仅用于本地排查;提交前应删除或替换为脱敏报告。 +- 由于 `gitleaks` 未安装,本次密钥扫描只是 grep 兜底,不等价于完整 secrets audit。