用途
Security and Hardening 面向 Web 应用的 security-first 开发实践。它的基本立场是:把每一个外部输入都当作敌意的,把每一个 secret 都当作神圣的,把每一次 authorization 检查都当作强制的。Security 不是一个阶段,而是对每一行接触用户数据、认证或外部系统的代码的约束。
何时使用
- 构建任何接受用户输入的东西
- 实现 authentication 或 authorization
- 存储或传输敏感数据
- 集成外部 API 或服务
- 添加文件上传、webhooks 或 callbacks
- 处理支付或 PII 数据
- 审计某个输入处理函数是否存在漏洞
- 检查登录流程是否安全、是否符合 OWASP Top Ten
- 审计依赖中的已知漏洞,分流包管理器的 audit 结果
流程:威胁建模优先
没有 threat model 就往上堆 controls,那只是猜测。在做加固之前,先花五分钟像攻击者一样思考:画出 trust boundaries,标注不可信数据在哪些位置进入系统(HTTP 请求、表单字段、文件上传、webhooks、第三方 API、消息队列、LLM 输出,以及其他进程的命令行或环境变量、共享卷上的文件名、job payload 里的路径);信任跟随的是写入某个值的人,而不是传送它的通道。随后点名资产(Credentials、PII、支付数据、admin 操作、资金流转),对每条边界跑一遍 STRIDE——Spoofing、Tampering、Repudiation、Information disclosure、Denial of service、Elevation of privilege。并在每个 use case 旁边写下 abuse case,把答案变成第一个测试。如果说不清某个功能的 trust boundaries,就还没准备好保护它,这正是 OWASP 的 A04: Insecure Design。
三层边界系统
Always Do(没有例外):在所有系统边界校验全部外部输入;参数化所有数据库查询,绝不把用户输入拼接进 SQL;对输出做编码以防 XSS;所有外部通信使用 HTTPS;用 bcrypt/scrypt/argon2 对密码做 hash;设置安全 headers;对 session 使用 httpOnly、secure、sameSite cookies;每次发布前用检测到的包管理器的原生 audit 针对已提交的 lockfile 跑一遍。
Ask First(需要人工批准):新增 authentication 流程或修改 auth 逻辑;存储新类别的敏感数据;新增外部服务集成;修改 CORS 配置;添加文件上传处理器;修改 rate limiting 或 throttling;授予更高权限或角色。
绝不执行:绝不把 secrets 提交到版本控制;绝不在日志里记录敏感数据;绝不把客户端校验当作安全边界;绝不为图省事而禁用安全 headers;绝不对用户提供的数据使用 eval() 或 innerHTML;绝不把 sessions 存放在客户端可访问的存储里;绝不向用户暴露 stack traces 或内部错误细节。
OWASP Top 10 防护模式
资料给出的预防模式覆盖:Injection(SQL、NoSQL、OS Command)使用参数化查询或带参数化输入的 ORM;Broken Authentication 使用带 salt rounds 的密码 hash 与安全 session 配置;XSS 使用框架自动转义,必要时先经 DOMPurify sanitize;Broken Access Control 要求在认证之外检查资源归属;Security Misconfiguration 使用 helmet 与 CSP、限制 CORS 到已知来源;Sensitive Data Exposure 要求不返回敏感字段并使用环境变量保存 secrets;SSRF 要求对用户影响的 URL 做 scheme 与 host allowlist、拒绝私有/保留 IP、禁止重定向,并注意 check 与 fetch 之间仍存在 TOCTOU gap,高风险场景需固定解析后的 IP 或前置过滤代理。
输入校验与文件上传
在边界进行 Schema Validation,例如用 zod 定义 schema 并在 route handler 用 safeParse 校验。文件上传需限制类型与大小,不信任文件扩展名,关键场景检查 magic bytes。
对派生路径的破坏性操作:一次 delete、move 或 overwrite 的安全性只取决于命名目标那个值的来源。发起破坏性调用前三个条件缺一不可——解析后的目标位于某个 allowlisted root 之下(解析 symlink 之后比较)、至少在该 root 之下一层、并带有属于你的证据且该证据要在操作前读取。拒绝执行时记下被拒绝的目标然后停止。资料同时指出两个局限:树内部的标记文件是自我声明,期望的 owner 必须来自已认证状态且标记需完整性保护;先解析路径再对名字操作存在 check/use race,共享卷上应使用不跟随 symlink、限定在 root 之下的操作。
依赖审计分流与供应链卫生
包管理器的 audit 报告的是已知 advisories;它既不证明一个包值得信任,也不证明易受攻击的代码是可达的。资料给出按 critical/high、moderate、low 分级的决策树,关键问题是:易受攻击的函数在代码路径里真的被调用吗?依赖是 runtime 还是仅开发使用?结合部署上下文是否可利用?推迟修复时记录原因并设定复查日期。供应链方面,应先找到 installation boundary 和 manager(使用拥有 lockfile 的 workspace 根目录),交叉验证 packageManager、lockfile 和 CI;首次执行前阻断依赖脚本;绝不自动应用强制 audit 修复;在支持的地方验证 registry 签名和 provenance;把新依赖、lockfile diff 和 script-policy 变更放在一起 review。
Rate Limiting 与 Secrets 管理
一般 API 与 auth 端点应分别设置限流,并注意进程数超过一个时需使用共享存储(如 Redis 或 @upstash/ratelimit),否则实际限额会被放大或永不触发。Secrets 管理要求 .env 不入库、示例文件可提交,.gitignore 包含 .env、.env.local、.pem、.key,提交前检查暂存内容;secret 一旦提交就当作已泄露并立即轮换。
数据隐私与合规
保护数据问的是攻击者能否读到它;Privacy 问的是是否该持有、该持有多久。资料主张把个人数据当作要最小化的负债:做数据分类(非个人、PII、敏感),最小化并设定目的,事先设定保留期限并真的删除(含备份、缓存、搜索索引、分析副本),支持数据主体权利(导出、更正、删除),收集或第三方共享前取得可审计的同意,默认值本地化而非硬编码某一地区法律。
AI / LLM 功能安全
应用调用 LLM 会继承新的攻击面,资料映射到 OWASP Top 10 for LLM Applications (2025):把所有模型输出当作不可信输入(LLM05);假设 prompts 可能被劫持(LLM01),system prompt 不是安全边界;让 secrets 和其他用户数据远离 prompts(LLM02 / LLM07);约束工具和 agent 权限(LLM06);限制消耗(LLM10);隔离检索数据(LLM08)。示例展示应解析并校验模型输出后再执行 allowlisted 操作,而不是直接查询或写入 innerHTML。
安全审查检查清单与常见合理化借口
资料附有覆盖 Authentication、Authorization、Input、Data、Infrastructure、Supply Chain、AI / LLM 的检查清单,以及 ../../references/security-checklist.md 中的详细条目与 pre-commit 验证步骤。文档还列出常见自我合理化(如“这是内部工具,security 不重要”)及对应现实反驳。