mcpField
V
VibeSec-Skill

VibeSec-Skill

github.com/behisecc安全1.4k1.1k 次安装36 周前更新
代码仓库

关于 VibeSec-Skill

面向 AI 助手的 Web 应用安全编码指南,涵盖客户端与服务端常见漏洞及防护要点。适合在实现或审查 Web 代码时作为检查参考。

主要功能

  1. 01访问控制与权限检查
  2. 02XSS 与 CSRF 防护
  3. 03敏感数据与密钥保护
  4. 04开放重定向防护
  5. 05密码存储建议
  6. 06SSRF 防护策略

适用场景

  1. 01检查资源访问授权逻辑
  2. 02审查表单及页面的 XSS 风险
  3. 03核对状态变更请求的 CSRF 防护
  4. 04检查重定向与 URL 请求处理

安装

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

$npx skills add https://github.com/behisecc/vibesec-skill --skill vibesec-skill

安装后在 Claude Code 中输入/vibesec-skill确认已加载。

附带文件README.mdLICENSE

详细介绍

Web 应用安全编码指南

概述

本指南全面介绍了 Web 应用的安全编码实践。作为 AI 助手,你的职责是以漏洞猎人的视角审视代码,在不破坏功能的前提下,让应用尽可能安全。

核心原则:

  • 纵深防御:绝不依赖单一安全控制措施
  • 安全失败:发生故障时应默认拒绝访问
  • 最小权限:仅授予必要的最低权限
  • 输入验证:绝不信任用户输入,在服务器端验证所有内容
  • 输出编码:根据数据呈现的上下文对其进行适当编码

访问控制问题

当用户能够访问超出其预期权限的资源或执行超出其权限的操作时,就会出现访问控制漏洞。

核心要求

对于每个需要身份验证的数据项和操作:

  1. 用户级授权

    • 每位用户只能访问或修改自己的数据
    • 任何用户都不应访问其他用户或组织的数据
    • 始终在数据层验证所有权,而不只是检查路由级别
  2. 使用 UUID 而非连续 ID

    • 使用 UUIDv4 或类似的不可猜测标识符
    • 例外:只有用户明确要求时才使用连续 ID
  3. 账户生命周期处理

    • 用户从组织中移除时:立即撤销其所有访问令牌和会话
    • 账户被删除或停用时:使所有活动会话和 API 密钥失效
    • 实现令牌撤销列表,或使用带刷新机制的短期令牌
授权检查清单
  • 每次请求都验证用户是否拥有该资源(不要信任客户端数据)
  • 对多租户应用检查组织成员资格
  • 对基于角色的操作验证角色权限
  • 权限变更后重新验证权限
  • 检查父资源的所有权(例如,访问评论时,验证用户是否拥有其所属的帖子)
需要避免的常见陷阱
  • IDOR(不安全的直接对象引用):始终验证请求用户是否有权访问所请求的资源 ID
  • 权限提升:在服务器端验证角色变更;绝不信任来自客户端的角色信息
  • 水平越权:用户 A 以相同权限级别访问用户 B 的资源
  • 垂直越权:普通用户访问管理员功能
  • 批量赋值:筛选用户可更新的字段;不要盲目接受请求正文中的所有字段
实现模式
# Pseudocode for secure resource access
function getResource(resourceId, currentUser):
    resource = database.find(resourceId)
    
    if resource is null:
        return 404  # Don't reveal if resource exists
    
    if resource.ownerId != currentUser.id:
        if not currentUser.hasOrgAccess(resource.orgId):
            return 404  # Return 404, not 403, to prevent enumeration
    
    return resource

客户端漏洞

跨站脚本(XSS)

所有可由用户直接或间接控制的输入都必须经过处理,以防范 XSS。

需要防护的输入来源

直接输入:

  • 表单字段(电子邮件、姓名、个人简介、评论等)
  • 搜索查询
  • 上传时使用的文件名
  • 富文本编辑器 / 所见即所得内容

间接输入:

  • URL 参数和查询字符串
  • URL 片段(哈希值)
  • 应用中使用的 HTTP 标头(显示 Referer、User-Agent 时)
  • 向用户展示的第三方 API 数据
  • WebSocket 消息
  • 来自 iframe 的 postMessage 数据
  • 被渲染的 LocalStorage/SessionStorage 值

常被忽略的输入:

  • 反映用户输入的错误消息
  • 接受 HTML 的 PDF / 文档生成器
  • 包含用户数据的电子邮件模板
  • 管理面板中的日志查看器
  • 被渲染为 HTML 的 JSON 响应
  • SVG 文件上传(可能包含 JavaScript)
  • Markdown 渲染(允许 HTML 时)
防护策略
  1. 输出编码(特定上下文)

    • HTML 上下文:进行 HTML 实体编码(< → &lt;)
    • JavaScript 上下文:进行 JavaScript 转义
    • URL 上下文:进行 URL 编码
    • CSS 上下文:进行 CSS 转义
    • 使用框架内置的转义功能(React 的 JSX、Vue 的 {{ }} 等)
  2. 内容安全策略(CSP)

    Content-Security-Policy: 
      default-src 'self';
      script-src 'self';
      style-src 'self' 'unsafe-inline';
      img-src 'self' data: https:;
      font-src 'self';
      connect-src 'self' https://api.yourdomain.com;
      frame-ancestors 'none';
      base-uri 'self';
      form-action 'self';
    
    • 脚本应避免使用 'unsafe-inline' 和 'unsafe-eval'
    • 必要时,为内联脚本使用 nonce 或哈希
    • 报告违规情况:report-uri /csp-report
  3. 输入清理

    • 使用成熟的库(HTML 可使用 DOMPurify)
    • 为富文本设置允许标签和属性的白名单
    • 移除或编码危险模式
  4. 其他标头

    • X-Content-Type-Options: nosniff
    • X-Frame-Options: DENY(或使用 CSP frame-ancestors)

跨站请求伪造(CSRF)

每个会更改状态的端点都必须防范 CSRF 攻击。

需要 CSRF 防护的端点

已认证操作:

  • 所有 POST、PUT、PATCH、DELETE 请求
  • 任何会更改状态的 GET 请求(应修正为使用适当的 HTTP 方法)
  • 文件上传
  • 设置变更
  • 支付/交易端点

认证前操作:

  • 登录端点(防止登录 CSRF)
  • 注册端点
  • 密码重置请求端点
  • 密码更改端点
  • 邮箱/手机验证端点
  • OAuth 回调端点
防护机制
  1. CSRF 令牌

    • 生成在密码学上安全的随机令牌
    • 将令牌与用户会话绑定
    • 在每个会更改状态的请求中进行验证
    • 登录后重新生成(防止会话固定组合攻击)
  2. SameSite Cookie

    Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly
    
    • Strict:Cookie 绝不会跨站发送(安全性最高)
    • Lax:Cookie 会在顶级导航时发送(平衡性较好)
    • 始终与 CSRF 令牌结合使用,构建纵深防御
  3. 双重提交 Cookie 模式

    • 在 Cookie 和请求正文/标头中同时发送 CSRF 令牌
    • 由服务端验证两者是否匹配
边缘情况和常见错误
  • 令牌存在性检查:CSRF 验证绝不能取决于令牌是否存在,必须始终要求提供令牌
  • 每个表单使用一个令牌:对于敏感操作,可考虑为每个表单使用唯一令牌
  • JSON API:不要认为 JSON 内容类型就能防止 CSRF;应验证 Origin/Referer 标头并使用令牌
  • CORS 配置错误:过于宽松的 CORS 可能绕过 SameSite Cookie
  • 子域名:CSRF 令牌应设置作用域,因为子域名接管可能导致 CSRF
  • Flash/PDF 上传:旧版浏览器插件可能绕过 SameSite
  • 带副作用的 GET 请求:绝不要在 GET 请求中更改状态
  • 令牌泄露:不要在 URL 中包含 CSRF 令牌
  • URL 中的令牌与标头中的令牌:优先使用自定义标头(X-CSRF-Token),而非 URL 参数
验证清单
  • 令牌在密码学上安全且随机(使用安全的随机数生成器)
  • 令牌与用户会话绑定
  • 服务端会验证所有会更改状态的请求中的令牌
  • 缺少令牌 = 拒绝请求
  • 认证状态变更时会重新生成令牌
  • 已设置 SameSite Cookie 属性
  • 会话 Cookie 已设置 Secure 和 HttpOnly 标志

密钥和敏感数据泄露

客户端代码不应访问任何密钥或敏感信息。

绝不要在客户端代码中暴露

API 密钥和机密:

  • 第三方 API 密钥(Stripe、AWS 等)
  • 数据库连接字符串
  • JWT 签名密钥
  • 加密密钥
  • OAuth 客户端机密
  • 内部服务 URL/凭据

敏感用户数据:

  • 完整信用卡号
  • 社会安全号码
  • 密码(即使经过哈希处理)
  • 安全问题/答案
  • 完整电话号码(应隐藏部分号码:--1234)
  • 显示时并不需要的敏感个人身份信息(PII)

基础设施详情:

  • 内部 IP 地址
  • 数据库架构
  • 调试信息
  • 生产环境中的堆栈跟踪
  • 服务器软件版本
密钥藏在哪里(请检查以下位置!)
  • JavaScript 包(包括源映射)
  • HTML 注释
  • 隐藏表单字段
  • 数据属性
  • LocalStorage/SessionStorage
  • SSR 应用中的初始状态/水合数据
  • 通过构建工具暴露的环境变量(NEXT_PUBLIC_、REACT_APP_)
最佳实践
  1. 环境变量:将密钥存储在 .env 文件中
  2. 仅限服务端:需要使用密钥的 API 调用只能从后端发起

开放重定向

任何接受 URL 并据此进行重定向的端点,都必须防范开放重定向攻击。

防护策略
  1. 允许列表验证

    allowed_domains = ['yourdomain.com', 'app.yourdomain.com']
    
    function isValidRedirect(url):
        parsed = parseUrl(url)
        return parsed.hostname in allowed_domains
    
  2. 仅允许相对 URL

    • 只接受路径(例如 /dashboard),不接受完整 URL
    • 验证路径以 / 开头且不包含 //
  3. 间接引用

    • 使用映射而不是原始 URL:?redirect=dashboard → 查找对应的 /dashboard
需要阻止的绕过技术
技术示例原理
@ 符号https://[email protected]浏览器会以 legit.com 为用户名,跳转到 evil.com
子域名滥用https://legit.com.evil.comevil.com 拥有该子域名
协议技巧javascript:alert(1)通过重定向实施 XSS
URL 双重编码%252f%252fevil.com双重解码后变为 //evil.com
反斜杠https://legit.com\@evil.com某些解析器会将 \ 规范化为 /
空字节https://legit.com%00.evil.com某些解析器会在空字节处截断
制表符/换行符https://legit.com%09.evil.com利用空白字符造成解析混淆
Unicode 规范化https://legіt.com(西里尔字母 і)IDN 同形异义字符攻击
Data URLdata:text/html,<script>...直接执行载荷
协议相对 URL//evil.com使用当前页面的协议
片段滥用https://legit.com#@evil.com不同库的解析结果不同
IDN 同形异义字符攻击防护
  • 验证前将 URL 转换为 Punycode
  • 对于敏感重定向,可考虑完全阻止非 ASCII 域名

密码安全
密码要求
  • 至少 8 个字符(建议 12 个或更多)
  • 不设最大长度(或设置较高上限,例如 128 个字符)
  • 允许所有字符,包括特殊字符
  • 不强制要求特定字符类型(让用户自行选择强密码)
存储
  • 使用 Argon2id、bcrypt 或 scrypt
  • 绝不要使用 MD5、SHA1 或普通 SHA256

服务端漏洞

服务端请求伪造(SSRF)

任何服务器会向用户提供或影响的 URL 发起请求的功能,都必须受到保护。

可能存在漏洞的功能
  • Webhook(用户提供回调 URL)
  • URL 预览
  • 根据 URL 生成 PDF
  • 根据 URL 获取图像/文件
  • 从 URL 导入的功能
  • RSS/Feed 阅读器
  • 使用用户提供端点的 API 集成
  • 代理功能
  • HTML 转 PDF/图像转换器
防护策略
  1. 允许列表方式(首选)

    • 仅允许向预先批准的域名发起请求
    • 为集成维护严格的允许列表
  2. 网络分段

    • 在隔离网络中运行 URL 获取服务
    • 阻止访问内部网络和云元数据
需要拦截的 IP 和 DNS 绕过技术
技术示例描述
十进制 IPhttp://2130706433127.0.0.1 的十进制表示
八进制 IPhttp://0177.0.0.1八进制表示
十六进制 IPhttp://0x7f.0x0.0x0.0x1十六进制表示
IPv6 本地主机http://[::1]IPv6 回环地址
IPv4 映射 IPv6http://[::ffff:127.0.0.1]映射 IPv4 的 IPv6 地址
简写 IPv6http://[::]全零地址
DNS 重绑定攻击者的 DNS 返回内部 IP第一次请求解析到外部 IP,第二次解析到内部 IP
指向内部地址的 CNAME攻击者的域名将 CNAME 指向内部地址DNS 指向内部主机名
URL 解析器混淆http://attacker.com#@internal不同的解析行为
重定向链外部 URL 重定向到内部地址谨慎处理重定向
IPv6 区域 IDhttp://[fe80::1%25eth0]接口范围内的 IPv6 地址
少见的 IP 格式http://127.1缩写 IP 表示法
防止 DNS 重绑定
  1. 发起请求前解析 DNS
  2. 验证解析出的 IP 不是内部地址
  3. 为该请求固定解析出的 IP(不要重新解析)
  4. 或者:间隔一段时间解析两次,确保两次都解析到相同的外部 IP
云元数据保护

阻止访问云元数据端点:

  • AWS:169.254.169.254
  • GCP:metadata.google.internal、169.254.169.254、http://metadata
  • Azure:169.254.169.254
  • DigitalOcean:169.254.169.254
实施检查清单
  • 验证 URL scheme 仅为 HTTP/HTTPS
  • 解析 DNS 并验证 IP 不是私有或内部地址
  • 明确拦截云元数据 IP
  • 限制或禁用重定向跟随
  • 如果跟随重定向,验证每一跳
  • 为请求设置超时时间
  • 限制响应大小
  • 尽可能使用网络隔离

不安全的文件上传

文件上传必须验证类型、内容和大小,以防止各种攻击。

验证要求

1. 文件类型验证

  • 根据允许列表检查文件扩展名
  • 验证魔数/文件签名是否与预期类型匹配
  • 绝不能只依赖单项检查

2. 文件内容验证

  • 读取并验证魔数
  • 对于图像:尝试使用图像库处理(以检测格式错误的文件)
  • 对于文档:扫描宏和嵌入对象
  • 检查多态文件(可被识别为多种类型的文件)

3. 文件大小限制

  • 在服务端设置最大文件大小
  • 同时配置 Web 服务器/代理限制
  • 考虑按文件类型设置限制(图像的限制应小于视频)
常见绕过方式和攻击
攻击描述防护措施
扩展名绕过shell.php.jpg检查完整扩展名,使用允许列表
空字节shell.php%00.jpg清理文件名,检查空字节
双重扩展名shell.jpg.php仅允许单个扩展名
MIME 类型伪造将 Content-Type 设置为 image/jpeg验证魔数
魔数字节注入在恶意文件前添加有效的魔数字节检查整个文件结构,而不只是文件头
多态文件同时作为 JPEG 和 JavaScript 有效的文件按预期类型解析文件,无效时拒绝
含 JavaScript 的 SVG<svg onload="alert(1)">清理 SVG 或完全禁止
通过文件上传进行 XXE恶意 DOCX、XLSX(它们基于 XML)在解析器中禁用外部实体
ZIP 路径穿越压缩包中的 ../../../etc/passwd验证解压后的路径
ImageMagick 漏洞利用特制图像保持 ImageMagick 更新,使用 policy.xml
文件名注入文件名中包含 ; rm -rf /清理文件名,使用随机名称
Content-Type 混淆浏览器 MIME 类型嗅探设置 X-Content-Type-Options: nosniff
魔数字节参考
类型魔数字节(十六进制)
JPEGFF D8 FF
PNG89 50 4E 47 0D 0A 1A 0A
GIF47 49 46 38
PDF25 50 44 46
ZIP50 4B 03 04
DOCX/XLSX50 4B 03 04(基于 ZIP)
安全处理上传文件
  1. 重命名文件:使用随机 UUID 名称,丢弃原文件名
  2. 存储在 Web 根目录之外:或为上传文件使用单独的域名
  3. 使用正确的响应头:
    • Content-Disposition: attachment(强制下载)
    • X-Content-Type-Options: nosniff
    • Content-Type 与实际文件类型一致
  4. 使用 CDN/单独的域名:将上传内容与主应用隔离
  5. 设置严格的权限:上传的文件不应具有可执行权限

SQL 注入

当用户输入未经妥善处理便被纳入 SQL 查询时,就会发生 SQL 注入。

预防方法

1. 参数化查询(预处理语句) — 首要防御手段

-- VULNERABLE
query = "SELECT * FROM users WHERE id = " + userId

-- SECURE
query = "SELECT * FROM users WHERE id = ?"
execute(query, [userId])

2. 使用 ORM

  • 使用会自动进行参数化的 ORM 方法
  • 谨慎使用 ORM 中的原始查询方法
  • 注意 ORM 特有的注入点

3. 输入验证

  • 验证数据类型(整数应为整数)
  • 在适用的情况下,对允许的值使用白名单
  • 这是纵深防御手段,而非首要防御手段
需要注意的注入点
  • WHERE 子句
  • ORDER BY 子句(常被忽略——不能使用参数,必须使用白名单)
  • LIMIT/OFFSET 的值
  • 表名和列名(不能参数化——必须使用白名单)
  • INSERT 的值
  • UPDATE SET 的值
  • 使用动态列表的 IN 子句
  • LIKE 模式(还要对通配符进行转义:%、_)
其他防御措施
  • 最小权限原则:数据库用户应仅拥有所需的最低权限
  • 禁用危险函数:例如 SQL Server 中的 xp_cmdshell
  • 错误处理:绝不要向用户暴露 SQL 错误

XML 外部实体(XXE)

当 XML 解析器处理用户提供的 XML 中的外部实体引用时,就会产生 XXE 漏洞。

易受攻击的场景

直接输入 XML:

  • SOAP API
  • XML-RPC
  • XML 文件上传
  • 配置文件解析
  • RSS/Atom Feed 处理

间接输入 XML:

  • 在服务端将 JSON/其他格式转换为 XML
  • Office 文档(DOCX、XLSX、PPTX 是包含 XML 的 ZIP 文件)
  • SVG 文件(基于 XML)
  • SAML 断言
  • 带有 XFA 表单的 PDF
按语言/解析器进行防护

Java:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setExpandEntityReferences(false);

Python(lxml):

from lxml import etree
parser = etree.XMLParser(resolve_entities=False, no_network=True)
# Or use defusedxml library

PHP:

libxml_disable_entity_loader(true);
// Or use XMLReader with proper settings

Node.js:

// Use libraries that disable DTD processing by default
// If using libxmljs, set { noent: false, dtdload: false }

.NET:

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.XmlResolver = null;
XXE 防护检查清单
  • 尽可能完全禁用 DTD 处理
  • 禁用外部实体解析
  • 禁用外部 DTD 加载
  • 禁用 XInclude 处理
  • 使用已应用最新补丁的 XML 解析器版本
  • 如果需要 DTD,在解析前验证/清理 XML
  • 在可行的情况下,考虑使用 JSON 替代 XML

路径遍历

当用户输入控制文件路径,从而允许访问预期目录之外的文件时,就会产生路径遍历漏洞。

易受攻击的模式
# VULNERABLE
file_path = "/uploads/" + user_input
file_path = base_dir + request.params['file']
template = "templates/" + user_provided_template
防护策略

1. 避免在路径中使用用户输入

# Instead of using user input directly
# Use indirect references
files = {'report': '/reports/q1.pdf', 'invoice': '/invoices/2024.pdf'}
file_path = files.get(user_input)  # Returns None if invalid

2. 规范化与验证

import os

def safe_join(base_directory, user_path):
    # Ensure base is absolute and normalized
    base = os.path.abspath(os.path.realpath(base_directory))
    
    # Join and then resolve the result
    target = os.path.abspath(os.path.realpath(os.path.join(base, user_path)))
    
    # Ensure the commonpath is the base directory
    if os.path.commonpath([base, target]) != base:
        raise ValueError("Error!")
    
    return target

3. 输入清理

  • 移除或拒绝 .. 序列
  • 移除或拒绝绝对路径标识符(/、C:)
  • 将允许的字符列入白名单(字母数字、连字符、下划线)
  • 在适用的情况下验证文件扩展名
路径遍历检查清单
  • 绝不要直接在文件路径中使用用户输入
  • 规范化路径,并验证其是否位于基准目录内
  • 在适用的情况下限制文件扩展名
  • 使用各种编码和绕过技术进行测试

安全响应头检查清单

在所有响应中包含以下响应头:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: [see XSS section]
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Cache-Control: no-store (for sensitive pages)

JWT 安全

JWT 配置错误可能导致身份验证被完全绕过以及令牌伪造。

漏洞
漏洞防护措施
alg: none 攻击始终在服务端验证算法,拒绝 none
算法混淆明确指定预期算法,绝不根据令牌推导算法
HMAC 密钥强度不足使用 256 位以上的密码学安全随机密钥
缺少过期时间始终设置 exp 声明
令牌存储在 localStorage 中使用 httpOnly、Secure、SameSite=Strict Cookie 存储,绝不存储在 localStorage 中
安全实现
// 1. SIGNING
// Always use environment variables for secrets
const secret = process.env.JWT_SECRET; 

const token = jwt.sign({
  sub: userId,
  iat: Math.floor(Date.now() / 1000),
  exp: Math.floor(Date.now() / 1000) + (15 * 60), // 15 mins (Short-lived)
  jti: crypto.randomUUID() // Unique ID for revocation/blacklisting
}, secret, { 
  algorithm: 'HS256' 
});

// 2. SENDING (Cookie Best Practices)
// Protect against XSS and CSRF
res.cookie('token', token, {
  httpOnly: true, 
  secure: true,    
  sameSite: 'strict'
});

// 3. VERIFYING
// CRITICAL: Whitelist the allowed algorithm
jwt.verify(token, secret, { algorithms: ['HS256'] }, (err, decoded) => {
  if (err) {
    // Handle invalid token
  }
  // Trust the payload
});
JWT 检查清单
  • 验证时明确指定算法(绝不信任令牌头)
  • 拒绝 alg: none
  • 密钥是 256 位以上的随机数据(不是密码或短语)
  • 始终设置并验证 exp 声明
  • 将令牌存储在 httpOnly Cookie 中(而非 localStorage/sessionStorage)
  • 实现刷新令牌轮换(旧刷新令牌在使用后失效)

API 安全

批量赋值

接受未经筛选的请求正文可能导致权限提升。

// VULNERABLE — user can set { role: "admin" } in request body
User.update(req.body)

// SECURE — whitelist allowed fields
const allowed = ['name', 'email', 'avatar']
const updates = pick(req.body, allowed)
User.update(updates)

这适用于任何 ORM/框架——始终明确指定请求可以修改哪些字段。

GraphQL
漏洞防护措施
在生产环境中启用内省在生产环境中禁用内省。
查询深度攻击限制查询深度(例如,最多 10 层)。
查询复杂度攻击计算并严格限制查询开销。
批处理攻击限制单个请求允许的操作数量。
const server = new ApolloServer({
  introspection: process.env.NODE_ENV !== 'production',
  validationRules: [
    depthLimit(10),
    costAnalysis({ maximumCost: 1000 })
  ]
})

通用安全原则

生成代码时,务必:

  1. 在服务端验证所有输入——绝不只依赖客户端验证
  2. 使用参数化查询——绝不将用户输入拼接到查询中
  3. 根据上下文对输出进行编码——HTML、JS、URL、CSS 上下文需要不同的编码方式
  4. 执行身份验证检查——检查每个端点,而不只是路由
  5. 执行授权检查——验证用户是否有权访问特定资源
  6. 使用安全的默认设置
  7. 安全地处理错误——不要向用户泄露堆栈跟踪或内部详细信息
  8. 及时更新依赖项——使用工具跟踪存在漏洞的依赖项

如有疑问,请选择限制更严格、更安全的选项,并在注释中记录相关安全考量。

评论

支持 Markdown