mcpField
S
security-testing-verification

security-testing-verification

github.com/harperaa安全19197 次安装45 周前更新
代码仓库

关于 security-testing-verification

security-testing-verification 是项目安全功能的测试与验证指南。它提供脚本、请求示例和部署清单,涵盖速率限制、CSRF、输入验证、安全标头及身份验证等防护。

主要功能

  1. 01测试速率限制及重置行为
  2. 02验证 CSRF 令牌处理
  3. 03检查输入验证与清理
  4. 04检查安全标头和身份验证
  5. 05运行依赖审计与安全脚本

适用场景

  1. 01开发期间验证 API 防护
  2. 02测试身份验证与授权行为
  3. 03部署前检查安全测试项

安装

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

$npx skills add https://github.com/harperaa/secure-claude-skills --skill security-testing-verification

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

详细介绍

安全测试与验证

内置安全测试

本项目为所有安全功能提供了自动化测试和验证脚本。

测试速率限制

自动化测试脚本
# Run the provided test script
node scripts/test-rate-limit.js

测试内容:

  • 向启用速率限制的端点连续发送 10 个请求
  • 验证前 5 个请求成功(HTTP 200)
  • 验证第 6 至第 10 个请求被阻止(HTTP 429)
  • 测试 60 秒后速率限制是否重置

预期输出:

Testing Rate Limiting (5 requests/minute per IP)
Request  1: ✓ 200 - Success
Request  2: ✓ 200 - Success
Request  3: ✓ 200 - Success
Request  4: ✓ 200 - Success
Request  5: ✓ 200 - Success
Request  6: ✗ 429 - Too many requests
Request  7: ✗ 429 - Too many requests
Request  8: ✗ 429 - Too many requests
Request  9: ✗ 429 - Too many requests
Request 10: ✗ 429 - Too many requests

✓ Rate limiting is working correctly!
手动测试
# Test rate limiting manually
for i in {1..10}; do
  echo "Request $i:"
  curl -s -o /dev/null -w "%{http_code}\n" \
    http://localhost:3000/api/test-rate-limit
  sleep 0.1
done

# Expected:
# Requests 1-5: 200
# Requests 6-10: 429
测试时间窗口后重置
# Make 5 requests
for i in {1..5}; do
  curl http://localhost:3000/api/test-rate-limit
done

# Wait 61 seconds (rate limit window = 60 seconds)
sleep 61

# Try again - should succeed
curl http://localhost:3000/api/test-rate-limit

# Expected: 200 OK (limit reset)

测试 CSRF 防护

测试 1:不带令牌的请求(应失败)
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -d '{"title": "test"}'

# Expected: 403 Forbidden
# {
#   "error": "CSRF token missing"
# }
测试 2:带有效令牌的请求(应成功)
# Step 1: Get CSRF token
TOKEN=$(curl -s http://localhost:3000/api/csrf \
  -c cookies.txt | jq -r '.csrfToken')

# Step 2: Use token in request
curl -X POST http://localhost:3000/api/example-protected \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: $TOKEN" \
  -d '{"title": "test"}'

# Expected: 200 OK
测试 3:重复使用令牌(应失败)
# Get token
TOKEN=$(curl -s http://localhost:3000/api/csrf \
  -c cookies.txt | jq -r '.csrfToken')

# Use once (succeeds)
curl -X POST http://localhost:3000/api/example-protected \
  -b cookies.txt \
  -H "X-CSRF-Token: $TOKEN" \
  -d '{"title": "test"}'

# Try to reuse same token (should fail)
curl -X POST http://localhost:3000/api/example-protected \
  -b cookies.txt \
  -H "X-CSRF-Token: $TOKEN" \
  -d '{"title": "test2"}'

# Expected: 403 Forbidden - Token already used
测试 4:无效令牌(应失败)
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: fake-token-12345" \
  -d '{"title": "test"}'

# Expected: 403 Forbidden
# {
#   "error": "CSRF token invalid"
# }

测试输入验证

测试 XSS 清理
# Test script tags removal
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: <get-token-first>" \
  -d '{"title": "<script>alert(1)</script>"}'

# Expected: 200 OK
# Title sanitized to: "alert(1)"
# < and > removed
测试长度验证
# Test too-long input
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: <token>" \
  -d "{\"title\": \"$(printf 'A%.0s' {1..200})\"}"

# Expected: 400 Bad Request
# {
#   "error": "Validation failed",
#   "details": {
#     "title": "String must contain at most 100 character(s)"
#   }
# }
测试电子邮件验证
curl -X POST http://localhost:3000/api/contact \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test User",
    "email": "not-an-email",
    "subject": "Test",
    "message": "Test message"
  }'

# Expected: 400 Bad Request
# {
#   "error": "Validation failed",
#   "details": {
#     "email": "Invalid email"
#   }
# }
测试必填字段
curl -X POST http://localhost:3000/api/contact \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test User"
  }'

# Expected: 400 Bad Request with missing field errors

测试安全标头

测试所有标头
curl -I http://localhost:3000

# Expected headers:
# Content-Security-Policy: default-src 'self'; ...
# X-Frame-Options: DENY
# X-Content-Type-Options: nosniff
# (HSTS only in production)
测试 CSP
# Check CSP includes required domains
curl -I http://localhost:3000 | grep "Content-Security-Policy"

# Should include:
# - script-src with Clerk domain
# - connect-src with Convex domain
# - frame-src with Stripe domain
测试 HSTS(仅限生产环境)
# In production environment
curl -I https://yourapp.com | grep "Strict-Transport-Security"

# Should return:
# Strict-Transport-Security: max-age=31536000; includeSubDomains
测试受保护路由的标头
curl -I http://localhost:3000/dashboard

# Should include:
# X-Robots-Tag: noindex, nofollow

测试身份验证

测试未经过身份验证的访问
# Try to access protected API without auth
curl http://localhost:3000/api/protected-endpoint

# Expected: 401 Unauthorized
# {
#   "error": "Unauthorized",
#   "message": "Authentication required"
# }
测试已通过身份验证的访问
# With valid Clerk session cookie
curl http://localhost:3000/api/protected-endpoint \
  -H "Cookie: __session=<clerk-session-token>"

# Expected: 200 OK (with authorized response)
测试授权(资源所有权)
# Try to access another user's resource
curl http://localhost:3000/api/posts/user-abc-post-123 \
  -H "Cookie: __session=<different-user-token>"

# Expected: 403 Forbidden
# {
#   "error": "Forbidden",
#   "message": "You do not have access to this resource"
# }
测试订阅限制
# Try premium feature with free account
curl http://localhost:3000/api/premium/generate \
  -H "Cookie: __session=<free-user-token>"

# Expected: 403 Forbidden
# {
#   "error": "Forbidden",
#   "message": "Premium subscription required"
# }

测试错误处理

测试生产环境错误消息
# Set NODE_ENV=production temporarily
export NODE_ENV=production

# Trigger error in API
curl http://localhost:3000/api/error-test

# Expected: Generic message (no stack trace)
# {
#   "error": "Internal server error",
#   "message": "An unexpected error occurred"
# }
测试开发环境错误消息
# In development (NODE_ENV=development)
curl http://localhost:3000/api/error-test

# Expected: Detailed error with stack trace
# {
#   "error": "Internal server error",
#   "message": "Specific error message",
#   "stack": "Error: ...\n    at ...",
#   "context": "error-test"
# }

测试依赖项安全性

运行 npm 审计
# Check for vulnerabilities
npm audit

# Expected: 0 vulnerabilities
# found 0 vulnerabilities
运行生产环境审计
# Only check production dependencies
npm audit --production

# Expected: 0 vulnerabilities
检查过时的软件包
npm outdated

# Expected: All packages up-to-date
# (or list of safe minor/patch updates available)
运行安全检查脚本
bash scripts/security-check.sh

# Expected:
# - 0 vulnerabilities
# - Minimal outdated packages
# - Fix commands if needed

在线安全测试工具

安全标头扫描器

工具: https://securityheaders.com/

使用方法:

  1. 部署应用
  2. 在 Security Headers 扫描器中输入 URL
  3. 检查是否获得 A+ 评级

检查内容:

  • Content-Security-Policy
  • X-Frame-Options
  • X-Content-Type-Options
  • Strict-Transport-Security
  • Referrer-Policy
  • Permissions-Policy
Mozilla Observatory

工具: https://observatory.mozilla.org/

使用方法:

  1. 输入已部署的 URL
  2. 运行扫描
  3. 查看评分(目标为 A+)

检查内容:

  • 安全标头
  • Cookie 安全性
  • HTTPS 配置
  • 子资源完整性
  • 内容安全策略
SSL Labs

工具: https://www.ssllabs.com/ssltest/

使用方法:

  1. 输入域名
  2. 等待扫描完成(约需 2 分钟)
  3. 检查是否获得 A+ 评级

检查内容:

  • SSL/TLS 配置
  • 证书有效性
  • 协议支持
  • 密码套件强度
  • HSTS 配置

部署前安全检查清单

每次部署到生产环境前,请逐项完成此检查清单:

环境与配置
  • 已在生产环境中设置所有环境变量
  • 已生成并配置 CSRF_SECRET(至少 32 字节)
  • 已生成并配置 SESSION_SECRET(至少 32 字节)
  • 已配置 Clerk 生产密钥
  • 已配置 Stripe 实时模式密钥(如使用支付功能)
  • 未将 .env.local 提交到 git
依赖项
  • 运行 npm audit --production——0 个漏洞
  • 运行 npm outdated——检查关键更新
  • 已提交 package-lock.json
  • Next.js 使用最新稳定版本
安全功能
  • 已测试 CSRF 防护(参见上文测试)
  • 已测试速率限制(参见上文测试)
  • 已测试输入验证(参见上文测试)
  • 已验证安全标头(securityheaders.com)
  • 已在生产环境中启用 HSTS
  • 生产环境中的错误消息为通用消息
身份验证与授权
  • 受保护路由要求进行身份验证
  • 访问前检查资源所有权
  • 为高级功能验证订阅状态
  • 验证 Webhook 签名(Clerk、Stripe)
  • 妥善处理会话过期
API 安全
  • 所有 POST/PUT/DELETE 路由都启用了 CSRF 保护
  • 所有公开端点都启用了速率限制
  • 使用 Zod 验证所有用户输入
  • 使用错误处理实用工具处理所有错误
  • 日志中不包含敏感数据
  • 代码中没有硬编码密钥
支付安全(如适用)
  • 使用 Clerk Billing + Stripe(不直接处理银行卡信息)
  • 已验证 Webhook(Svix 签名)
  • 在服务端检查订阅状态
  • 生产环境中已禁用测试模式
测试
  • 运行速率限制测试:node scripts/test-rate-limit.js
  • 手动测试 CSRF 保护
  • 使用恶意输入测试输入验证
  • 检查安全标头:curl -I https://yourapp.com
  • 测试身份验证流程
  • 在生产模式下测试错误处理
监控
  • 已配置错误日志记录(Vercel 日志)
  • 已跟踪身份验证失败尝试(Clerk 控制面板)
  • 已启用 GitHub Dependabot 警报
  • 已监控安全标头(自动化检查)

自动化测试脚本

security-test.sh

创建一个全面的测试脚本:

#!/bin/bash

echo "================================="
echo "Security Testing Suite"
echo "================================="
echo ""

# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Test counter
PASSED=0
FAILED=0

# Function to run test
run_test() {
    local test_name=$1
    local command=$2
    local expected=$3

    echo -n "Testing $test_name... "

    result=$(eval $command 2>&1)

    if echo "$result" | grep -q "$expected"; then
        echo -e "${GREEN}✓ PASS${NC}"
        ((PASSED++))
    else
        echo -e "${RED}✗ FAIL${NC}"
        echo "  Expected: $expected"
        echo "  Got: $result"
        ((FAILED++))
    fi
}

echo "=== Dependency Security ==="
run_test "npm audit" "npm audit --production" "found 0 vulnerabilities"

echo ""
echo "=== Rate Limiting ==="
echo "Running rate limit test script..."
node scripts/test-rate-limit.js

echo ""
echo "=== Security Headers ==="
run_test "X-Frame-Options" "curl -I http://localhost:3000" "X-Frame-Options: DENY"
run_test "X-Content-Type-Options" "curl -I http://localhost:3000" "X-Content-Type-Options: nosniff"
run_test "Content-Security-Policy" "curl -I http://localhost:3000" "Content-Security-Policy"

echo ""
echo "================================="
echo "Tests Passed: $PASSED"
echo "Tests Failed: $FAILED"
echo "================================="

if [ $FAILED -eq 0 ]; then
    echo -e "${GREEN}All tests passed!${NC}"
    exit 0
else
    echo -e "${RED}Some tests failed!${NC}"
    exit 1
fi

运行方式:

bash scripts/security-test.sh

持续安全测试

添加到 CI/CD 管道
# .github/workflows/security.yml
name: Security Tests

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  security:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm ci

      - name: Run npm audit
        run: npm audit --production

      - name: Check for outdated packages
        run: npm outdated || true

      - name: Build application
        run: npm run build

      - name: Start server (background)
        run: npm run dev &
        env:
          NODE_ENV: test

      - name: Wait for server
        run: npx wait-on http://localhost:3000

      - name: Run security tests
        run: bash scripts/security-test.sh

      - name: Stop server
        run: pkill -f "npm run dev"

手动渗透测试

测试所有输入字段中的 XSS
  1. 在每个输入字段中尝试以下载荷:

    <script>alert('XSS')</script>
    <img src=x onerror=alert('XSS')>
    <svg onload=alert('XSS')>
    javascript:alert('XSS')
    "><script>alert('XSS')</script>
    
  2. 验证它们都已清理

测试 SQL 注入
  1. 在搜索/查询字段中尝试以下内容:

    ' OR '1'='1
    '; DROP TABLE users; --
    ' UNION SELECT * FROM users --
    
  2. 验证输入验证会拦截或清理输入

测试 CSRF
  1. 创建恶意 HTML 文件:

    <form action="http://localhost:3000/api/delete-account" method="POST">
      <input type="hidden" name="confirm" value="yes" />
    </form>
    <script>document.forms[0].submit();</script>
    
  2. 登录后打开该文件

  3. 验证请求已被阻止(403 Forbidden)

测试授权
  1. 以用户 A 的身份创建资源
  2. 尝试以用户 B 的身份访问/修改该资源
  3. 验证结果为 403 Forbidden

部署后需要监控的内容

每日
  • 错误率(Vercel 控制面板)
  • 身份验证失败尝试(Clerk 控制面板)
  • 速率限制违规情况(检查日志中是否有 429 响应)
每周
  • 运行 npm audit --production
  • 检查 GitHub Dependabot 警报
  • 查看错误日志,查找规律
每月
  • 全面安全审计
  • 更新依赖项
  • 重新运行安全测试套件
  • 检查安全标头(securityheaders.com)

参考资料

后续步骤

  • 修复问题:使用相应的安全技能(csrf-protection、rate-limiting 等)
  • 部署:完成上述部署前检查清单
  • 监控:在 CI/CD 中设置自动化安全扫描
  • 持续维护:每月运行安全审计

评论

支持 Markdown