关于 security
面向开发者的跨技术栈安全参考,适用于应用设计、实现、审查和事件响应,涵盖 OWASP Top 10、输入验证、身份验证、数据保护与密钥管理。
主要功能
- 01OWASP Top 10 风险指南
- 02输入验证与安全查询实践
- 03身份验证和授权模式
- 04数据保护与密钥管理
- 05HTTP 安全标头与 CORS
- 06安全审查清单及反模式
适用场景
- 01审查处理用户输入或敏感数据的代码
- 02设计身份验证与授权流程
- 03准备安全审计
- 04响应漏洞报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ krzysztofsurdy/ code-virtuoso --skill security安装后在 Claude Code 中输入/security确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/auth-patterns.mdowasp-top-10.mdsecure-coding.md详细介绍
安全
安全不是一项功能,而是每项功能都具备的属性。每个端点、每个表单、每条数据流、每个集成点,都必须从一开始就将安全纳入设计。在事后再补上安全措施,成本高、容易出错,而且往往并不完整。
本技能提供与技术栈无关的安全应用构建指南,涵盖 OWASP Top 10、输入验证、身份验证与授权模式、数据保护、机密管理、安全标头以及常见反模式。
适用场景
在以下情况下,请参考本技能:
- 设计会处理用户输入、身份验证或敏感数据的新功能
- 检查代码中的安全问题
- 实现身份验证或授权流程
- 处理机密、API 密钥或凭据
- 配置 HTTP 安全标头
- 评估某项依赖或设计选择是否会引入风险
- 为安全审计或渗透测试做准备
- 响应安全事件或漏洞报告
OWASP Top 10
OWASP Top 10(2021 年版)列出了 Web 应用最严重的安全风险。请将其作为起始检查清单,而非完整列表。
| # | 漏洞 | 含义 | 主要防御措施 |
|---|---|---|---|
| A01 | 访问控制失效 | 用户执行超出预期权限的操作 | 默认拒绝,在服务器端强制执行 |
| A02 | 加密机制失效 | 由于加密机制薄弱或缺失,导致敏感数据暴露 | 使用强算法,对传输中和静态数据进行加密 |
| A03 | 注入 | 不可信数据作为命令或查询的一部分发送给解释器 | 使用参数化查询,验证输入 |
| A04 | 不安全设计 | 设计中缺少或未有效实施安全控制 | 威胁建模,采用安全设计模式 |
| A05 | 安全配置错误 | 默认配置不安全,或配置不完整 | 采用强化的默认配置,自动验证配置 |
| A06 | 易受攻击的组件 | 使用存在已知漏洞的组件 | 扫描依赖项,及时更新 |
| A07 | 身份验证失效 | 身份验证或身份识别机制失效 | MFA、速率限制、安全存储密码 |
| A08 | 完整性失效 | 未验证代码或数据的完整性 | 对更新进行签名,检查 CI/CD 完整性 |
| A09 | 日志记录和监控失效 | 日志记录和监控不足 | 记录安全事件,设置告警 |
| A10 | SSRF | 服务器被诱骗发起非预期请求 | 将目标地址加入允许列表,清理 URL |
输入验证
输入验证是第一道防线。应在每个系统边界进行验证,而不只是 UI。
核心原则:
- 在服务器端验证——客户端验证只是为了提升用户体验,并非安全控制措施
- 优先使用允许列表,而非拒绝列表——明确哪些内容可接受,而不是试图拦截危险内容
- 验证类型、长度、格式和范围——“name”字段不应接受 10MB 的数据,也不应包含控制字符
- 拒绝意外输入——默认拒绝,不要试图“清理”恶意输入后继续处理
- 先规范化,再验证——在检查之前规范化 Unicode、解码 URL 编码并解析路径遍历
类型强制转换的危险:
宽松的类型比较可能绕过安全检查。字符串 "0" 根据语言不同,可能等于整数 0 或布尔值 false。始终使用严格比较运算符和显式类型转换。
参数化查询:
绝不要将用户输入拼接到 SQL、LDAP 或操作系统命令中。始终使用参数化查询或预处理语句。这也适用于 ORM——原始查询方法会绕过 ORM 的保护措施。详情请参阅安全编码参考。
身份验证模式
身份验证用于验证身份——“你是谁?”。详细指南请参阅身份验证模式参考。
密码哈希:
- 使用 bcrypt、scrypt 或 Argon2id——绝不要仅用 MD5、SHA-1 或 SHA-256 对密码进行哈希
- 每个密码都必须使用唯一盐值,并由哈希库生成
- 绝不要存储明文密码,也绝不要对密码使用可逆加密
- 强制执行最低复杂度要求,但避免过于严格的规则,以免促使用户采用更弱的模式
多因素身份验证(MFA):
- TOTP(基于时间的一次性密码)是基本要求
- WebAuthn/通行密钥可提供最强的抗网络钓鱼能力
- 基于 SMS 的 MFA 总比没有好,但容易受到 SIM 卡交换攻击
- 始终提供恢复代码
会话管理:
- 生成具有足够熵(128 位以上)的加密安全随机会话 ID
- 设置安全的 Cookie 属性:
HttpOnly、Secure、SameSite=Lax(或Strict) - 登录后重新生成会话 ID,以防止会话固定
- 设置绝对超时和空闲超时
- 注销时在服务器端使会话失效
基于令牌的身份验证(JWT 注意事项):
- JWT 不是会话——没有额外基础设施就无法撤销
- 始终在服务器端验证签名算法;拒绝
alg: none - 缩短令牌有效期(以分钟计,而非小时)
- 使用刷新令牌维持长期会话,并安全存储
- 绝不要在 JWT 负载中存储敏感数据——它们只是经过 Base64 编码,并未加密
OAuth2 流程:
- Authorization Code with PKCE——适用于 Web 和移动应用的标准流程
- Client Credentials——用于机器间通信
- 绝不要使用 Implicit 流程——出于安全原因,该流程已弃用
授权模式
授权决定权限——“你可以做什么?”授权不同于身份验证。详情请参阅身份验证模式参考。
最小权限原则:
- 仅授予完成任务所需的最低权限
- 默认拒绝——明确授予访问权限,而不是事后撤销
- 尽可能为提升后的权限设置有效期限
基于角色的访问控制(RBAC):
- 将权限分配给角色,再将角色分配给用户
- 角色应保持粗粒度;避免角色数量激增
- 在应用代码中检查权限,而不是角色名称——这样可将授权逻辑与角色定义解耦
基于属性的访问控制(ABAC):
- 根据用户、资源、操作和环境的属性做出决策
- 对于复杂策略(例如“经理可在工作时间内审批金额低于 $10,000 的费用”),比 RBAC 更灵活
- 复杂度更高——仅在 RBAC 无法满足需求时使用
常见的授权错误:
- 仅在 UI 中检查授权——务必在服务端强制执行
- 依赖隐蔽性(难以猜测的 URL),而非访问控制
- 未在每个请求中检查授权(包括 API 调用、文件下载和间接引用)
- IDOR(不安全的直接对象引用)——务必确认用户有权访问其请求的特定资源
数据保护
静态数据加密:
- 加密存储在数据库、文件和备份中的敏感数据
- 对称加密使用 AES-256 或同等算法
- 将加密密钥与加密数据分开管理
- 按计划轮换加密密钥,并在怀疑密钥遭到泄露时立即轮换
传输中数据加密:
- 所有网络通信均使用 TLS 1.2+
- 禁用较旧的协议(SSL、TLS 1.0、TLS 1.1)
- 正确验证证书——不要禁用证书验证
个人身份信息(PII)的处理:
- 识别并分类所有个人身份信息
- 尽量减少收集——不要收集不需要的数据
- 制定数据保留政策——不再需要时删除数据
- 为合规要求(GDPR、CCPA)提供数据导出和删除功能
- 在日志中屏蔽 PII——切勿记录密码、令牌、信用卡号或完整的 SSN
安全删除:
- 释放内存前覆盖敏感数据(在编程语言允许的情况下)
- 确保数据库删除操作确实移除数据(敏感记录不要仅做软删除)
- 考虑备份保留策略——已删除的数据可能仍存在于备份中
密钥管理
绝不将密钥放在代码或配置文件中:
- 不要将 API 密钥、密码或令牌放在源代码、配置文件或已提交到版本控制的特定环境文件中
- 使用
.gitignore忽略本地配置文件,但不要将其作为唯一的防护措施 - 扫描代码库,查找意外提交的密钥(可使用 git-secrets、truffleHog 或 Gitleaks 等工具)
环境变量:
- 适用于简单部署,但存在局限性
- 同一环境中的所有进程都可以看到它们
- 它们会出现在进程列表和崩溃转储中
- 比硬编码更好,但不是最安全的选项
密钥管理器:
- 使用专用的密钥管理器(HashiCorp Vault、AWS Secrets Manager、Azure Key Vault、GCP Secret Manager)
- 在运行时而非构建时访问密钥
- 审计密钥访问记录
轮换策略:
- 定期轮换密钥
- 怀疑密钥遭到泄露时立即轮换
- 设计系统以支持无停机轮换(过渡期间支持两个有效版本)
- 尽可能自动化轮换
安全响应头
在每个响应中配置以下 HTTP 响应头。每个响应头都针对特定类型的攻击。
| 响应头 | 用途 | 建议值 |
|---|---|---|
Content-Security-Policy (CSP) | 通过控制允许加载内容的来源来防止 XSS | 从限制严格的策略开始;避免使用 unsafe-inline 和 unsafe-eval |
Strict-Transport-Security (HSTS) | 强制所有后续请求使用 HTTPS | max-age=63072000; includeSubDomains; preload |
X-Content-Type-Options | 防止 MIME 类型嗅探 | nosniff |
X-Frame-Options | 通过控制 iframe 嵌入来防止点击劫持 | DENY 或 SAMEORIGIN |
Referrer-Policy | 控制发送多少引荐来源信息 | strict-origin-when-cross-origin |
Permissions-Policy | 控制浏览器功能(摄像头、麦克风、地理位置) | 禁用不使用的功能 |
CORS(跨源资源共享):
- 不要在需要身份验证的端点上使用
Access-Control-Allow-Origin: * - 将特定来源列入允许列表
- 严格限制
Access-Control-Allow-Methods和Access-Control-Allow-Headers - 请理解,CORS 由浏览器强制执行——它无法保护服务器到服务器的调用
常见反模式
以下是经常遇到的易造成漏洞的错误:
- 隐匿式安全 — 隐藏 URL、使用难以预测的 ID 或混淆代码都不属于安全控制措施。这些做法只能作为真正安全措施的补充,绝不能取而代之。
- 仅在客户端进行验证 — 在 JavaScript 或移动端代码中进行的任何验证都可以被绕过。务必在服务器端验证。
- 自行编写密码学实现 — 绝不要自行实现加密、哈希或随机数生成。请使用经过充分测试的库。
- 过度宽松的 CORS — 将
Access-Control-Allow-Origin: *与凭据结合使用会造成漏洞。请明确指定允许的来源。 - 在代码仓库中存储机密 — 即使是在“私有”仓库中,代码里的机密也会通过分支、CI 系统和开发者的计算机传播。
- 为方便而禁用安全功能 — 在“开发”模式中关闭 CSRF 防护、SSL 验证或身份验证,可能导致这些设置泄漏到生产环境。
- 信任内部网络 — 零信任意味着即使对于内部服务到服务的调用,也要验证身份和授权。
- 忽略依赖项漏洞 — 依赖项中的已知漏洞是最容易被利用的攻击途径之一。请定期扫描并更新依赖项。
- 记录敏感数据 — 在日志中记录密码、令牌、信用卡号和 PII,会造成二次暴露风险。
- 捕获并忽略异常 — 吞掉错误会掩盖安全故障。请记录错误(不要包含敏感信息),并以安全方式失败。
安全审查清单
在审查代码、设计功能或准备发布时,请使用此清单:
输入/输出:
- 所有用户输入都在服务器端进行验证
- 所有数据库操作都使用参数化查询
- 根据相应上下文(HTML、URL、JavaScript、SQL)对输出进行编码/转义
- 验证文件上传的类型、大小和内容;将文件存储在 Web 根目录之外
身份验证:
- 使用 bcrypt/Argon2id 对密码进行哈希处理
- 登录后重新生成会话 ID
- 设置安全 Cookie 属性(HttpOnly、Secure、SameSite)
- 对登录端点进行速率限制
- 在多次尝试失败后锁定账户或逐步延长等待时间
授权:
- 每个请求都在服务器端执行授权检查
- 遵循最小权限原则
- 验证直接对象引用是否属于当前用户
- 保护管理员功能,避免通过猜测 URL 访问
数据:
- 对静态存储和传输中的敏感数据进行加密
- 不记录个人身份信息(PII)
- 实施数据保留政策
- 对备份进行加密
配置:
- 源代码或配置文件中不包含机密信息
- 配置安全标头
- 在生产环境中禁用调试模式
- 错误消息不会向客户端泄露内部细节
- 扫描依赖项,检查是否存在已知漏洞
- 强制使用 TLS 1.2+;禁用较旧协议
监控:
- 记录安全事件(登录失败、授权拒绝、输入验证失败)
- 针对可疑模式配置警报
- 保护日志,防止被篡改
- 编写事件响应计划