mcpField
S
security-review

security-review

github.com/shiplightai安全2409 次安装16 周前更新
代码仓库

关于 security-review

security-review 是用于评估应用安全状况的审查流程,面向发布前检查、重大改动复核和安全审计准备。它结合代码库分析与浏览器测试,依据安全标准输出带证据的发现、修复建议和 YAML 回归测试。

主要功能

  1. 01攻击面与数据流梳理
  2. 02HTTP 安全头检查
  3. 03认证、会话与访问控制测试
  4. 04输入注入与客户端安全检查
  5. 05依赖及供应链审查
  6. 06报告、修复建议与 YAML 测试

适用场景

  1. 01发布前检查 Web 应用安全状况
  2. 02复核认证或授权改动
  3. 03为安全审计整理证据与发现
  4. 04安全事件后排查类似问题

安装

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

$npx skills add https://github.com/shiplightai/agent-skills --skill security-review

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

详细介绍

安全审查

依据行业标准评估应用的安全状况,并通过基于浏览器的渗透测试验证发现的问题。本次审查覆盖静态分析工具容易遗漏的攻击面,包括运行时行为、标头配置、身份验证流程和客户端漏洞。

使用时机

在以下情况下使用 /security-review:

  • 发布新应用或新功能之前
  • 添加身份验证或授权相关变更之后
  • 处理敏感数据(用户凭据、支付信息、个人身份信息)时
  • 准备安全审计时
  • 发生安全事件后,检查是否存在类似问题
  • 审查第三方集成时

参考标准

  • OWASP Top 10 (2021) — Web 应用的主要安全风险
  • OWASP ASVS v4.0 — 应用安全验证标准
  • OWASP Session Management Cheat Sheet
  • NIST 800-63B — 数字身份指南(身份验证)
  • CWE/SANS Top 25 — 最危险的软件弱点
  • Mozilla Observatory — HTTP 安全标头最佳实践

阶段概览

Phase 1: EDUCATE   → Security context and what we check
Phase 2: SCOPE     → Identify attack surface, auth mechanisms, data flows
Phase 3: ANALYZE   → Automated checks + browser-based penetration testing
Phase 4: REPORT    → Findings with evidence, CVE references, confidence scores
Phase 5: REMEDIATE → Fix guidance + YAML regression tests

阶段 1:说明

重要性: 数据泄露的平均成本为 445 万美元(IBM,2023 年)。83% 的 Web 应用至少存在一个严重漏洞。许多安全问题只有在运行时才能检测到,例如配置错误的标头、不安全的令牌存储和失效的访问控制,而这些正是基于浏览器的测试所能发现的问题。

本次审查通过基于浏览器的验证,依据客观安全标准检查你的应用。每项发现都引用了具体标准(OWASP、CWE、NIST)。


阶段 2:确定范围

收集背景信息
  1. 从代码库自动检测:

    • 身份验证机制(JWT、会话、OAuth、API 密钥)
    • 正在使用的框架安全功能(CSRF 令牌、CORS 配置、CSP)
    • 存在已知漏洞的依赖项(npm audit / pip audit)
    • API 路由和端点
    • 环境变量处理方式
    • 文件上传功能
    • 第三方脚本和 CDN 的使用情况
  2. 逐项询问用户:

    • 目标 URL:应用在哪里运行?
    • 身份验证机制:用户如何登录?(自动检测后请用户确认)
    • 测试凭据:你有可供我使用的测试账号吗?(身份验证测试所需)
    • 敏感数据:应用会处理哪些敏感数据?(个人身份信息、支付信息、健康记录)
    • 已知问题:你特别担心哪些方面?(可选)
  3. 梳理攻击面:

    • 列出所有用户输入点(表单、URL 参数、文件上传、WebSocket 消息)
    • 列出所有 API 端点及其身份验证要求
    • 列出所有第三方集成
    • 确认数据流:敏感数据从何处进入、如何处理和存储,以及从何处流出?

阶段 3:分析

使用 new_session 打开浏览器会话,并设置 record_evidence: true。运行所有适用类别的检查。

类别 A:HTTP 安全标头(HDR)
检查 ID检查项标准方法
HDR-01存在严格的 Content-Security-Policy 标头OWASP A05检查响应标头
HDR-02Strict-Transport-Security(HSTS)设置了较长的 max-ageOWASP Transport检查标头是否存在及其值
HDR-03X-Content-Type-Options: nosniffMozilla Observatory检查标头
HDR-04设置了 X-Frame-Options 或 CSP frame-ancestorsOWASP Clickjacking检查标头
HDR-05Referrer-Policy 设置恰当Privacy/Security检查标头值
HDR-06Permissions-Policy 限制了敏感 APIBrowser security检查摄像头、麦克风和地理位置策略
HDR-07不通过 Server/X-Powered-By 泄露版本信息Information leak检查标头中是否包含版本字符串
HDR-08为敏感页面设置 Cache-ControlOWASP Session检查已认证内容是否设置了 no-store
HDR-09CORS 限制不过于宽松OWASP A05检查 Access-Control-Allow-Origin
HDR-10不存在混合内容(HTTPS 页面加载 HTTP 资源)Transport security检查所有资源 URL

浏览器验证: 使用 act 通过 JavaScript 检查 document.querySelector('meta[http-equiv]'),并通过同源请求获取响应标头。使用 get_browser_console_logs 检查是否有混合内容警告。

类别 B:身份验证与会话管理(AUTH)
检查 ID检查项标准方法
AUTH-01不将令牌存储在 localStorage 中OWASP ASVS 3.3.2检查 localStorage/sessionStorage 中是否有令牌
AUTH-02会话 Cookie 设置了 HttpOnly 标志OWASP Session检查 Set-Cookie 标头
AUTH-03会话 Cookie 设置了 Secure 标志OWASP Session检查 Set-Cookie 标头
AUTH-04会话 Cookie 设置了 SameSite 属性OWASP CSRF检查 Set-Cookie 标头
AUTH-05会话在空闲超时后过期OWASP ASVS 3.3.1等待并验证会话是否失效
AUTH-06注销会使服务器端会话失效OWASP ASVS 3.3.1注销后重放旧令牌,并检查响应
AUTH-07密码重置令牌只能使用一次OWASP Auth使用重置链接两次,验证第二次是否失败
AUTH-08URL 参数中不包含凭据OWASP Transport检查 URL 中是否有令牌/密码
AUTH-09登录设有暴力破解防护OWASP Auth多次尝试登录失败,检查是否锁定/限速
AUTH-10状态更改请求设有 CSRF 防护OWASP A01不带 CSRF 令牌提交表单
AUTH-11已验证 JWT 签名(如适用)OWASP Auth发送修改后的 JWT,并检查是否被拒绝
AUTH-12使用 OAuth state 参数(如适用)OWASP Auth检查 OAuth 流程是否包含 state 参数

浏览器验证: 使用 act 登录,通过 JavaScript 检查 Cookie(document.cookie——HttpOnly Cookie 不会显示,这是正确的)。检查 localStorage。执行注销并重放请求。尝试暴力破解(输入 5 次错误密码)。修改 JWT 令牌并进行测试。

类别 C:输入验证与注入(INJ)
检查 ID检查项标准方法
INJ-01XSS:页面中的反射型输入OWASP A03 / CWE-79在所有输入字段中提交 <script>alert(1)</script>,检查是否被渲染
INJ-02XSS:数据库中的存储型输入OWASP A03 / CWE-79通过表单提交脚本,检查后续页面加载时是否被渲染
INJ-03表单输入中的 SQL 注入OWASP A03 / CWE-89提交 ' OR '1'='1 模式,检查是否出现错误
INJ-04通过 URL 参数进行开放重定向CWE-601使用外部 URL 测试重定向参数
INJ-05文件操作中的路径遍历CWE-22在与文件相关的参数中测试 ../../etc/passwd
INJ-06输入字段中的命令注入CWE-78在输入可能传递到 shell 的位置测试 ; ls 或 `
INJ-07用户内容中的 HTML 注入CWE-79提交 HTML 标签,检查是否被渲染
INJ-08URL scheme 验证(javascript:)CWE-79在 URL 输入字段中测试 javascript:alert(1)
INJ-09文件上传验证OWASP A04上传扩展名错误、体积过大或包含可执行内容的文件
INJ-10API 输入验证OWASP A03向 API 端点发送格式错误的 JSON、缺少字段或类型错误的数据

浏览器验证: 使用 act 在表单字段中填入测试载荷。提交后捕获页面状态。检查是否执行脚本、是否出现错误消息或异常行为。使用 get_browser_console_logs 查看可能表明存在注入向量的 JavaScript 错误。

重要提示: 这些是仅用于检测的非破坏性测试载荷。请勿尝试实际利用漏洞。基于 alert 的 XSS 测试使用 alert(1),没有危害。

类别 D:访问控制(AC)
检查 ID检查项标准方法
AC-01未通过身份验证时,受保护页面返回 401/403OWASP A01未通过身份验证时访问受保护的 URL
AC-02不存在 IDOR(不安全的直接对象引用)OWASP A01 / CWE-639更改 URL 中的资源 ID,检查是否可未经授权访问
AC-03API 端点强制执行授权OWASP A01使用错误或缺失的身份验证信息调用 API 端点
AC-04普通用户无法访问管理页面OWASP A01使用普通用户会话访问管理路由
AC-05客户端源代码中不包含敏感数据信息泄露检查 JavaScript 包中是否包含 API 密钥和机密信息
AC-06禁用目录列表信息泄露访问目录 URL(例如 /api/、/static/)
AC-07生产环境中未暴露调试端点OWASP A05检查常见调试路径(/debug、/trace、/graphql playground)
AC-08错误消息不会泄露内部详情OWASP A05触发错误,检查是否出现堆栈跟踪或数据库详情

浏览器验证: 未通过身份验证时访问受保护页面。尝试访问属于其他用户的资源。使用 act 执行 JavaScript,扫描脚本内容,检查是否存在硬编码的机密信息。

类别 E:客户端安全(CLI)
检查 ID检查项标准方法
CLI-01客户端存储中不含敏感数据OWASP 存储检查 localStorage、sessionStorage、IndexedDB
CLI-02CDN 资源启用子资源完整性(SRI)供应链检查外部脚本/样式表上的 integrity 属性
CLI-03第三方脚本清单供应链列出所有外部脚本来源
CLI-04不使用 eval() 或 innerHTML 处理用户输入CWE-79扫描 JavaScript 中的危险模式
CLI-05服务工作线程的作用域受到限制客户端安全检查 SW 注册作用域
CLI-06WebSocket 连接使用 WSS传输检查 WS 连接 URL
CLI-07控制台日志中不含敏感数据信息泄露检查 get_browser_console_logs 的输出
CLI-08点击劫持防护有效OWASP 点击劫持测试是否能在 iframe 中嵌入页面

浏览器验证: 使用 act 通过 JavaScript 枚举 localStorage 键,检查脚本标签的 SRI,并列出所有发往外部域名的网络请求。使用 get_browser_console_logs 检查是否有数据泄露。

类别 F:依赖项与供应链(DEP)
检查 ID检查项标准方法
DEP-01不存在已知存在漏洞的依赖项OWASP A06 / CWE-1035运行 npm audit / pip audit
DEP-02锁定文件存在且已提交供应链检查是否存在 package-lock.json / yarn.lock / pnpm-lock.yaml
DEP-03不存在不必要的依赖项攻击面检查未使用的包
DEP-04CDN 资源使用 SRI供应链检查完整性属性(与 CLI-02 相同)
DEP-05依赖项不存在仿冒包风险供应链将包名与已知包进行比对

验证: 运行依赖项审计命令。与第 2 阶段的代码库扫描结果交叉核对。


第 4 阶段:报告

生成结构化报告并保存到 shiplight/reports/security-review-{date}.md:

# Security Review Report
**Date:** {date}
**URL:** {url}
**Auth mechanism:** {type}
**Attack surface:** {summary}

## Overall Score: {X}/10 | Confidence: {X}%

## Score Breakdown
| Category | Score | Findings |
|----------|-------|----------|
| HTTP Headers (HDR) | 6/10 | 1 critical, 2 high |
| Auth & Sessions (AUTH) | 4/10 | 2 critical, 1 high |
| Input Validation (INJ) | 7/10 | 1 high, 2 medium |
| Access Control (AC) | 8/10 | 1 medium |
| Client-Side (CLI) | 5/10 | 1 critical, 1 high |
| Dependencies (DEP) | 9/10 | 1 low |

## Findings

### CRITICAL

#### AUTH-01: JWT stored in localStorage — XSS leads to full account takeover
- **Standard:** OWASP ASVS 3.3.2 / CWE-922
- **Finding:** Access token stored in `localStorage` under key `auth_token`, accessible to any XSS payload
- **Evidence:** [screenshot of Application > Storage showing JWT]
- **Attack scenario:** Any XSS vulnerability (even via third-party script) can exfiltrate all user tokens
- **CVSS estimate:** 8.1 (High)
- **Confidence:** 95%

...
置信度评分
  • 90-100%:已在浏览器中利用并验证(例如,XSS 载荷已执行,已确认存在未授权访问)
  • 70-89%:检查发现有力证据(例如,已确认缺少标头,观察到不安全的 Cookie 标志)
  • 50-69%:有代码层面的证据,但未在运行时充分验证
  • 低于 50%:不要报告——推测性太强

第 5 阶段:修复

对于每项发现,提供:

1. 修复指南
#### AUTH-01: JWT stored in localStorage
**Risk:** Any XSS → full account takeover
**File:** src/lib/auth.ts:47
**Current:** `localStorage.setItem('auth_token', jwt)`
**Fix:** Move to HttpOnly cookie set by the server
- Server: `Set-Cookie: token=<jwt>; HttpOnly; Secure; SameSite=Strict; Path=/`
- Client: Remove all localStorage token operations
- API calls: Cookies sent automatically (remove Authorization header)
**Migration steps:**
1. Add cookie-setting endpoint on server
2. Update API middleware to read from cookie
3. Remove client-side token storage
4. Update CORS to allow credentials
2. YAML 回归测试
- name: auth-01-no-tokens-in-localstorage
  description: Verify authentication tokens are not stored in localStorage
  severity: critical
  standard: OWASP-ASVS-3.3.2
  steps:
    - URL: /login
    - intent: Enter test username
      action: fill
      locator: "getByLabel('Email')"
      value: "[email protected]"
    - intent: Enter test password
      action: fill
      locator: "getByLabel('Password')"
      value: "testpass123"
    - intent: Click login button
      action: click
      locator: "getByRole('button', { name: 'Sign in' })"
    - WAIT_UNTIL: User is logged in and dashboard is visible
      timeout_seconds: 15
    - description: Assert no auth tokens are stored in localStorage
      js: |
        const keys = Object.keys(localStorage);
        const tokenKeys = keys.filter(k =>
          /token|jwt|auth|session|access/i.test(k)
        );
        if (tokenKeys.length > 0) {
          throw new Error(
            `Auth tokens found in localStorage: ${tokenKeys.join(', ')}`
          );
        }
    - VERIFY: No authentication tokens are stored in browser localStorage

将所有 YAML 测试保存到 shiplight/tests/security-review.test.yaml。


渗透测试深度级别

  • --quick:标头(HDR)+ Cookie 标志(AUTH-02/03/04)+ localStorage 检查(AUTH-01)+ 依赖项审计(DEP-01)。约 2 分钟。
  • 默认:所有类别,使用标准载荷。约 10 分钟。
  • --thorough:所有类别 + 扩展注入载荷 + IDOR 枚举 + 暴力破解测试 + 完整的第三方脚本分析。约 20-30 分钟。

提示

  • 始终使用测试凭据,切勿使用生产凭据
  • XSS 测试载荷不会造成破坏(alert(1)),可安全用于预发布环境
  • 进行已验证身份的测试时,登录后使用 save_storage_state 保存会话
  • 在基于浏览器的审查之前运行 npm audit,以便及早发现已知 CVE
  • 使用 get_browser_console_logs——许多安全问题都会产生控制台警告
  • 使用 close_session 关闭会话,并使用 generate_html_report 收集证据

评论

支持 Markdown