mcpField
S
security-and-hardening

security-and-hardening

github.com/maddec01安全115 次安装今天更新
代码仓库

关于 security-and-hardening

面向开发 Web 应用及处理用户数据、身份验证或外部系统的开发者。它结合威胁建模,提供输入校验、访问控制、隐私、依赖项和 LLM 功能安全方面的指导。

主要功能

  1. 01使用 STRIDE 进行威胁建模
  2. 02输入校验与访问控制
  3. 03身份验证与数据保护
  4. 04依赖项和供应链审查
  5. 05隐私与数据保留指导
  6. 06LLM 安全实践

适用场景

  1. 01为 Web 功能规划安全控制
  2. 02审查身份验证或文件上传变更
  3. 03加固处理外部输入的集成
  4. 04评估 LLM 功能的风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/maddec01/mux-factory --skill security-and-hardening

安装后在 Claude Code 中输入/security-and-hardening确认已加载。

附带文件references/hardening-patterns.md

详细介绍

安全与加固

概述

采用安全优先的 Web 应用开发实践。将每个外部输入视为恶意内容,将每个密钥视为至关重要的信息,并将每次授权检查视为必需步骤。安全不是一个阶段,而是对每一行涉及用户数据、身份验证或外部系统的代码的约束。

适用场景

  • 构建任何接受用户输入的内容
  • 实现身份验证或授权
  • 存储或传输敏感数据
  • 集成外部 API 或服务
  • 添加文件上传、Webhook 或回调
  • 处理支付或 PII 数据

流程:先进行威胁建模

没有威胁模型就硬加的控制措施,只能算猜测。加固之前,花五分钟换位思考,像攻击者一样思考:

  1. 梳理信任边界。 不可信数据会在哪里进入系统?HTTP 请求、表单字段、文件上传、Webhook、第三方 API、消息队列和 LLM 输出——还有一些看起来像内部数据、只是因为 OS 把它们交给你的本地值:另一个进程的命令行或环境变量、共享卷上的文件名、作业负载中的路径。信任取决于值的编写者,而非传递渠道。每个边界都是攻击面。
  2. 列出资产。 什么东西值得窃取或破坏?凭据、PII、支付数据、管理员操作、资金转移。
  3. 对每个边界进行 STRIDE 分析——这是一种快速审视方法,不是形式主义:
威胁要问的问题常见缓解措施
S 欺骗有人能冒充用户/服务吗?身份验证、签名验证
T 篡改数据在传输中或静态存储时能被修改吗?完整性检查、参数化查询、HTTPS
R 抵赖事后能否否认某项操作?记录安全事件的审计日志
I 信息泄露数据会泄露吗?加密、字段允许列表、通用错误信息
D 拒绝服务系统可能因不堪重负而瘫痪吗?速率限制、输入大小上限、超时
E 权限提升用户能获得不该拥有的权限吗?授权检查、最小权限
  1. 在使用场景旁边编写滥用场景。 对每项功能,都问一句“我会如何滥用它?”——然后把它作为第一个测试。

如果说不清某项功能的信任边界,就还没准备好保护它。这就是 OWASP A04:不安全设计——大多数安全漏洞始于设计,而非代码。

三级边界系统

始终执行(无例外)
  • 在系统边界(API 路由、表单处理程序)验证所有外部输入
  • 对所有数据库查询进行参数化处理——绝不将用户输入拼接到 SQL 中
  • 对输出进行编码以防止 XSS(使用框架的自动转义,不要绕过它)
  • 所有外部通信都使用 HTTPS
  • 使用 bcrypt/scrypt/argon2 对密码进行哈希处理(绝不存储明文密码)
  • 设置安全标头(CSP、HSTS、X-Frame-Options、X-Content-Type-Options)
  • 会话使用 httpOnly、secure、sameSite Cookie
  • 每次发布前,使用检测到的包管理器原生审计功能审计已提交的锁文件
先征求意见(需要人工批准)
  • 添加新的身份验证流程或更改身份验证逻辑
  • 存储新的敏感数据类别(PII、支付信息)
  • 添加新的外部服务集成
  • 更改 CORS 配置
  • 添加文件上传处理程序
  • 修改速率限制或节流设置
  • 授予更高权限或角色
绝不执行
  • 绝不将密钥提交到版本控制中(API 密钥、密码、令牌)
  • 绝不记录敏感数据(密码、令牌、完整信用卡号)
  • 绝不将客户端验证视为安全边界
  • 绝不为了方便而禁用安全标头
  • 绝不对用户提供的数据使用 eval() 或 innerHTML
  • 绝不将会话存储在客户端可访问的存储中(例如使用 localStorage 存储身份验证令牌)
  • 绝不向用户暴露堆栈跟踪或内部错误详情

加固控制

以下规则构成工作流;每项规则的具体实现见 references/hardening-patterns.md。用到相关代码时再打开所需章节,无需提前查看。

注入、XSS 和访问控制
  • 对每个查询使用参数化方式。绝不根据输入字符串构造 SQL、NoSQL 或 shell 命令。
  • 通过框架的自动转义功能对输出进行编码。如果无法避免使用原始 HTML,须先通过允许列表清理器进行清理。
  • 每个请求都要检查授权,而不仅是身份验证:经过身份验证的用户必须拥有特定资源,或获准访问该资源(A01,IDOR)。

模式:注入、XSS、访问控制。

身份验证和会话
  • 使用 bcrypt(≥12 轮)、scrypt 或 argon2 对密码进行哈希处理。会话密钥必须来自环境变量,不能写在代码中。
  • 会话 Cookie 必须设置 httpOnly、secure 和 sameSite: 'lax' 或 'strict'(用于防御 CSRF;'none' 会在跨站请求中发送 Cookie),并设置有界的 maxAge。

模式:身份验证。

标头、CORS 和响应
  • 每个响应都要包含安全标头(使用 helmet 或框架的等效功能);CSP 从 default-src 'self' 开始,并逐步收紧,而不是放宽。
  • CORS 仅允许配置中明确列出的来源。启用凭据时,绝不能使用 *。
  • 在发送任何响应前,移除敏感字段(passwordHash、重置令牌)。错误响应正文应使用通用内容;内部信息只能写入服务端日志。

模式:错误配置、敏感数据泄露。

输入验证和上传
  • 在边界处使用 schema 进行验证:允许列表中的结构、长度、枚举值和格式。拒绝时返回 422 和结构化详情;下游代码只能使用解析后的类型化值。
  • 上传:使用允许列表限制 MIME 类型、限制大小,并在必要时验证内容(魔数)。文件扩展名不能证明任何内容。

模式:Schema 验证、文件上传。

服务端抓取(SSRF)

用户能够影响的任何 URL——webhook、从 URL 导入、图片代理、链接预览——都可能被指向内部服务。使用允许列表限制 scheme 和 host,解析所有 DNS 记录并拒绝任何私有或保留地址(回环、链路本地 169.254.169.254、私有地址、IPv4 和 IPv6 的唯一本地地址),并禁止重定向。此检查仍存在 DNS 重绑定 TOCTOU 漏洞:对于高风险入口,应固定已解析的 IP,或在前面设置过滤 Agent。

模式:SSRF。

对派生路径执行破坏性操作

删除、移动或覆盖操作的安全性取决于用于指定目标的值;信任应取决于该值的写入者,而不是传递它的渠道:另一个进程的命令行与表单字段一样,都可能受攻击者控制。形状检查只能证明格式正确,不能证明已获授权。调用前必须同时满足以下三项:解析后的目标(已解析符号链接)位于允许列表中的根目录之下;目标至少位于该根目录下一层;并且目标具有在操作前读取的所有权证据。拒绝时,记录被拒绝的目标并停止;绝不能回退到范围更广的默认路径。

为什么这项检查并没有看起来那么可靠(标记自我证明、检查与使用之间的竞争条件):破坏性路径。示例代码:../../references/security-checklist.md。

速率限制

对 API 实施常规限流,并严格限制身份验证端点(每 15 分钟约 10 次尝试)。一旦多个进程开始处理流量,内存计数器就会悄然变成 max × instances,或者在无服务器环境中完全不触发:请使用共享存储作为限流器的后端。

模式:速率限制。

密钥

密钥来自环境变量。提交 .env.example 并使用占位符;将真实的 .env* 文件和密钥材料加入 gitignore;提交前检查暂存的差异。密钥一旦到达远程端,就已泄露:先轮换密钥,再清除历史记录。

模式:密钥管理。

依赖项和供应链
  1. 找到安装边界和包管理器。 使用拥有锁文件的工作区根目录;只有在独立的嵌套项目位于该工作区之外时,才使用该项目。交叉核对 packageManager(如有)、锁文件和 CI;如果信息不一致或存在多个竞争的锁文件,请停止操作。固定包管理器版本。
  2. 首次执行前阻止依赖项脚本。 禁用脚本或采用有文档记录的默认拒绝策略进行引导;检查待执行脚本的源代码,只批准最低限度的脚本,提交策略,然后通过干净的冻结/不可变安装进行验证。切勿一概批准。
  3. 每次发布前,使用已提交的锁文件运行原生审计。 根据可达性(运行时、构建、测试、部署路径)确定严重/高危问题的优先级,并修复影响可用性的问题。切勿自动执行强制修复(npm audit fix --force 或同类操作),因为强制修复可能超出已声明的依赖范围;请先预览、阅读变更日志,并逐项测试升级。每项延期都要记录理由和复审日期。
  4. 审计只能匹配已知公告。 它们无法发现新出现的恶意包或仿冒包(cross-env 与 crossenv)。请一并审查新增依赖项、锁文件差异和脚本策略变更:所有权、维护情况、发布年限、来源证明和传递依赖图。支持的情况下验证注册表签名(npm audit signatures、pnpm audit signatures);如果缺少签名,应将其视为需要调查的信号,而非自动认定已遭入侵(A06、LLM03)。

确定处理优先级的决策树:依赖项审计分流。包管理器矩阵和安装脚本门控:../../references/security-checklist.md。

个人数据与隐私

安全加固关注“攻击者能否读取它?”,隐私关注“我们是否应该持有它?要持有多久?”最容易保护、应对泄露和满足合规要求的数据,就是从未收集的数据;请将个人数据视为需要尽量减少的责任。

  • 添加字段时对其进行分类(非个人数据、PII、敏感数据),并据此处理各类数据。找不到数据,就无法保护它,也无法响应删除请求。
  • 仅为明确说明的目的收集数据。“以后可能有用”是潜在的数据泄露范围,不是收集目的。不要在遥测数据中包含 PII(observability-and-instrumentation 技能也从运维角度强调了这一点)。
  • 预先设定保留期限,并真正删除数据。 每个个人数据存储都需要 TTL 和可用的删除路径,包括备份、缓存、搜索索引和分析副本。
  • 支持司法管辖区要求的数据主体权利(GDPR、CCPA 等):导出、更正、删除。设计架构时,应确保能够找到并删除用户数据,而不是让数据不可逆地散布到各个系统中。
  • 收集数据和向第三方共享数据均须经过同意,并且同意过程可供审计。 将 PII 发送给分析、广告或大模型供应商即构成共享;供应商需要签署数据处理协议。将地区设为可配置的策略,而非硬编码的假设。

分类表:数据分类。隐私事件会启动数据泄露通知时限;请使用 debugging-and-error-recovery 技能进行事后复盘。

AI / LLM 功能

调用大模型——聊天机器人、摘要工具、Agent、RAG——会带来新的攻击面;请参照 OWASP 大模型应用十大风险(2025)梳理这些风险:

  • 模型输出是不可信输入(LLM05)。绝不能将其传入 eval、SQL、shell、innerHTML 或文件路径;应谨慎解析,根据架构验证,然后编码。
  • 提示词可能被劫持(LLM01)。上下文中的不可信文本——用户消息、抓取的页面、PDF——都可能包含指令。系统提示词不是安全边界;请在代码中强制执行权限。
  • 不要将机密、其他租户的数据和完整系统提示词放入上下文窗口(LLM02、LLM07);限定工具权限,验证每个工具参数,并确认破坏性操作(LLM06);限制 token 数量、请求速率和递归深度(LLM10);按租户划分 RAG 嵌入,并在索引前验证文档(LLM08)。

模式:LLM 输出处理。

审查清单

签核前,请逐项检查 ../../references/security-checklist.md:其中涵盖身份验证、授权、输入、数据保护与隐私、标头与 CORS、依赖项与供应链、AI/LLM 和错误处理,以及 OWASP 快速参考表。

常见借口

借口实际情况
“这是内部工具,安全不重要”内部工具也会遭到入侵。攻击者会瞄准最薄弱的一环。
“以后再加安全措施”事后补上安全措施要比一开始就纳入设计难 10 倍。现在就加上。
“没人会试图利用这个”自动化扫描器会找到它。依赖隐蔽性并不等于安全。
“框架会处理安全问题”框架提供的是工具,而非保障。你仍然需要正确使用这些工具。
“这只是个原型”原型会进入生产环境。从第一天起就养成安全习惯。
“在这里做威胁建模太过了”花五分钟想想“我会如何攻击它?”,就能避免那些事后无法靠任何控制措施修补的设计缺陷。
“这只是大模型的输出,只是文本”这种“文本”可能是 SQL 语句、脚本标签或 shell 命令。应将其视为任何其他不可信输入。
“审计通过了,所以依赖项是安全的”审计针对的是已知公告。它无法发现新出现的恶意软件包,也无法确保未经审查的安装脚本可安全执行。
“先收集起来,以后可能用得上”不持有的数据就不会遭遇泄露、传票或误删。“可能用得上”属于泄露范围,而非收集目的。
“我们会手动处理删除请求”手动删除会漏掉备份、缓存和分析数据副本。如果架构无法找到用户的数据,就无法满足其请求——请从设计上考虑这一点。
“合规是法务的事,不是我们的事”导出、删除、保留和同意都是架构与代码的一部分。要是你已将个人身份信息散落在十个系统中,法务也无法事后补上这些功能。

红旗问题

  • 用户输入直接传入数据库查询、Shell 命令或 HTML 渲染
  • 删除、移动或覆盖操作的目标来自载荷、配置值或其他进程的命令行,且仅通过路径格式检查加以防护
  • 源代码或提交历史中包含密钥
  • API 端点没有身份验证或授权检查
  • 缺少 CORS 配置,或允许通配符(*)来源
  • 身份验证端点没有速率限制,或在多个实例前使用内存中的限流器
  • 向用户暴露堆栈跟踪或内部错误
  • 依赖项存在已知严重漏洞、同一安装边界存在相互竞争的锁文件、安装过程不可复现,或脚本一律获准运行
  • 服务端获取用户提供的 URL,且没有使用允许列表(SSRF)
  • 将 LLM/模型输出传入查询、DOM、Shell 或 eval
  • 将密钥、PII 或完整系统提示词放入 LLM 上下文窗口
  • 收集个人数据,却未说明用途、保留期限或删除途径
  • 未经同意或未签订数据处理协议,就将 PII 发送给分析、广告或 LLM 服务商
  • “删除我的账户”只切换了一个标记,个人数据却仍留在存储系统和备份中

验证

实施与安全相关的代码后:

  • 原生审计不存在未缓解且可触达的严重/高危问题;CI 保留权威锁文件,并阻止未经审核的依赖脚本
  • 源代码或 git 历史中没有密钥
  • 在系统边界验证所有用户输入
  • 在执行破坏性文件系统操作前,先解析符号链接,再验证允许的根路径、最小深度和所有权
  • 在每个受保护的端点检查身份验证和授权
  • 响应中包含安全标头(使用浏览器 DevTools 检查)
  • 错误响应不会暴露内部详情
  • 身份验证端点已启用速率限制;当多个实例提供流量服务时,使用共享存储支持限流
  • 根据允许列表验证服务端 URL 获取操作(避免 SSRF)
  • 使用前验证并编码 LLM/模型输出(如存在 AI 功能)
  • 对个人数据进行分类,按明确用途尽量减少收集,并设定保留期限
  • 删除和导出请求端到端可用(包括备份、缓存和分析副本)

评论

支持 Markdown