15 KiB
当前项目安全漏洞检查计划
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为准。- 安全扫描不应把真实密钥写入仓库;发现疑似密钥时只记录文件位置、变量名、脱敏片段和处置建议。
总体策略
- 先做仓库状态和范围确认,避免扫描其他 worktree 或错误路径。
- 优先运行不会修改文件的安全检查:
npm audit --json、cargo audit、密钥扫描、危险代码模式扫描。 - 分前端供应链、后端供应链、源码安全、配置/脚本安全四类归档。
- 对结果按严重级别分层:Critical / High / Medium / Low / Informational。
- 对每个真实问题给出:影响范围、证据、可行修复、验证命令、是否需要业务回归。
- 只有在用户确认进入执行/修复阶段后,才做依赖升级、代码修复、文档更新、测试和提交。
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:
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:
npm --version
node --version
cargo --version
rustc --version
可选只读清单:
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:
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:
优先:
cargo audit --json --manifest-path server-rs/Cargo.toml > /tmp/genarrative-cargo-audit.json
cargo audit --manifest-path server-rs/Cargo.toml
如果本机没有 cargo audit:
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:
gitleaks detect --source . --no-git --redact --report-format json --report-path /tmp/genarrative-gitleaks.json
如果没有 gitleaks,先用只读 grep/ripgrep 兜底:
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:
# 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:
# 安全漏洞扫描报告 YYYY-MM-DD
## 扫描范围
## 扫描命令与环境
## 摘要
## Critical
## High
## Medium
## Low
## Informational / False Positive
## 依赖升级建议
## 代码修复建议
## 需要人工确认的问题
## 验证命令
Validation:
- 报告不包含真实密钥。
- 每条问题都有“证据、影响、建议、验证”。
- 明确哪些是工具扫描结果,哪些是人工判断。
Task 9: 如用户要求修复,再分批执行最小修复
Objective: 避免一次性大规模升级导致回归,把修复拆为可验证的小批次。
Suggested order:
- Critical secrets:立即移除、轮换密钥、补
.gitignore/文档约束(注意项目约束:不要在.gitignore中添加.env.local)。 - Critical/High direct dependencies:优先升级 direct dependency,运行最小测试。
- Critical/High transitive dependencies:评估是否由 direct dependency patch/minor 升级带出。
- 源码漏洞:按入口编写回归测试,再修复。
- Medium/Low:按风险和 breaking change 代价排期。
Required verification after fixes:
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 修复涉及运行态时,还需要:
npm run api-server
# 另一个终端检查 /healthz 并执行对应 smoke
Validation:
- 修复后重新跑对应 audit / secret scan。
- 走
requesting-code-review的独立安全复核流程。
Files likely to change(仅修复阶段)
本计划阶段不修改以下文件;只有用户确认执行修复时才可能变化:
package.jsonpackage-lock.jsonapps/admin-web/package.jsonserver-rs/Cargo.tomlserver-rs/Cargo.lockserver-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
安全扫描执行阶段:
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
修复执行阶段:
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:
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 凭据和生产运行时配置,需要另行确认访问范围和凭据边界。