security-testing-verification

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Security Testing & Verification

安全测试与验证

Built-In Security Tests

内置安全测试

This project includes automated tests and verification scripts for all security features.
本项目包含针对所有安全功能的自动化测试和校验脚本。

Testing Rate Limiting

测试速率限制

Automated Test Script

自动化测试脚本

bash
undefined
bash
undefined

Run the provided test script

Run the provided test script

node scripts/test-rate-limit.js

**What it tests:**
- Makes 10 consecutive requests to rate-limited endpoint
- Verifies first 5 succeed (HTTP 200)
- Verifies requests 6-10 are blocked (HTTP 429)
- Tests rate limit reset after 60 seconds

**Expected output:**
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!
undefined
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!
undefined

Manual Testing

手动测试

bash
undefined
bash
undefined

Test rate limiting manually

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
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:

Expected:

Requests 1-5: 200

Requests 1-5: 200

Requests 6-10: 429

Requests 6-10: 429

undefined
undefined

Test Reset After Window

测试窗口到期后重置

bash
undefined
bash
undefined

Make 5 requests

Make 5 requests

for i in {1..5}; do curl http://localhost:3000/api/test-rate-limit done
for i in {1..5}; do curl http://localhost:3000/api/test-rate-limit done

Wait 61 seconds (rate limit window = 60 seconds)

Wait 61 seconds (rate limit window = 60 seconds)

sleep 61
sleep 61

Try again - should succeed

Try again - should succeed

Expected: 200 OK (limit reset)

Expected: 200 OK (limit reset)

undefined
undefined

Testing CSRF Protection

测试CSRF防护

Test 1: Request Without Token (Should Fail)

测试1:不带Token的请求(应当失败)

bash
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -d '{"title": "test"}'
bash
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -d '{"title": "test"}'

Expected: 403 Forbidden

Expected: 403 Forbidden

{

{

"error": "CSRF token missing"

"error": "CSRF token missing"

}

}

undefined
undefined

Test 2: Request With Valid Token (Should Succeed)

测试2:带有效Token的请求(应当成功)

bash
undefined
bash
undefined

Step 1: Get CSRF token

Step 1: Get CSRF token

TOKEN=$(curl -s http://localhost:3000/api/csrf
-c cookies.txt | jq -r '.csrfToken')
TOKEN=$(curl -s http://localhost:3000/api/csrf
-c cookies.txt | jq -r '.csrfToken')

Step 2: Use token in request

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"}'
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

Expected: 200 OK

undefined
undefined

Test 3: Token Reuse (Should Fail)

测试3:Token复用(应当失败)

bash
undefined
bash
undefined

Get token

Get token

TOKEN=$(curl -s http://localhost:3000/api/csrf
-c cookies.txt | jq -r '.csrfToken')
TOKEN=$(curl -s http://localhost:3000/api/csrf
-c cookies.txt | jq -r '.csrfToken')

Use once (succeeds)

Use once (succeeds)

curl -X POST http://localhost:3000/api/example-protected
-b cookies.txt
-H "X-CSRF-Token: $TOKEN"
-d '{"title": "test"}'
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)

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"}'
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

Expected: 403 Forbidden - Token already used

undefined
undefined

Test 4: Invalid Token (Should Fail)

测试4:无效Token(应当失败)

bash
curl -X POST http://localhost:3000/api/example-protected \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: fake-token-12345" \
  -d '{"title": "test"}'
bash
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

Expected: 403 Forbidden

{

{

"error": "CSRF token invalid"

"error": "CSRF token invalid"

}

}

undefined
undefined

Testing Input Validation

测试输入验证

Test XSS Sanitization

测试XSS清理

bash
undefined
bash
undefined

Test script tags removal

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>"}'
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

Expected: 200 OK

Title sanitized to: "alert(1)"

Title sanitized to: "alert(1)"

< and > removed

< and > removed

undefined
undefined

Test Length Validation

测试长度验证

bash
undefined
bash
undefined

Test too-long input

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})"}"
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

Expected: 400 Bad Request

{

{

"error": "Validation failed",

"error": "Validation failed",

"details": {

"details": {

"title": "String must contain at most 100 character(s)"

"title": "String must contain at most 100 character(s)"

}

}

}

}

undefined
undefined

Test Email Validation

测试邮箱验证

bash
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"
  }'
bash
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

Expected: 400 Bad Request

{

{

"error": "Validation failed",

"error": "Validation failed",

"details": {

"details": {

"email": "Invalid email"

"email": "Invalid email"

}

}

}

}

undefined
undefined

Test Required Fields

测试必填字段

bash
curl -X POST http://localhost:3000/api/contact \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test User"
  }'
bash
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

Expected: 400 Bad Request with missing field errors

undefined
undefined

Testing Security Headers

测试安全头

Test All Headers

测试所有头信息

bash
curl -I http://localhost:3000
bash
curl -I http://localhost:3000

Expected headers:

Expected headers:

Content-Security-Policy: default-src 'self'; ...

Content-Security-Policy: default-src 'self'; ...

X-Frame-Options: DENY

X-Frame-Options: DENY

X-Content-Type-Options: nosniff

X-Content-Type-Options: nosniff

(HSTS only in production)

(HSTS only in production)

undefined
undefined

Test CSP

测试CSP

bash
undefined
bash
undefined

Check CSP includes required domains

Check CSP includes required domains

curl -I http://localhost:3000 | grep "Content-Security-Policy"
curl -I http://localhost:3000 | grep "Content-Security-Policy"

Should include:

Should include:

- script-src with Clerk domain

- script-src with Clerk domain

- connect-src with Convex domain

- connect-src with Convex domain

- frame-src with Stripe domain

- frame-src with Stripe domain

undefined
undefined

Test HSTS (Production Only)

测试HSTS(仅生产环境)

bash
undefined
bash
undefined

In production environment

In production environment

curl -I https://yourapp.com | grep "Strict-Transport-Security"
curl -I https://yourapp.com | grep "Strict-Transport-Security"

Should return:

Should return:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Strict-Transport-Security: max-age=31536000; includeSubDomains

undefined
undefined

Test Protected Route Headers

测试受保护路由的头信息

bash
curl -I http://localhost:3000/dashboard
bash
curl -I http://localhost:3000/dashboard

Should include:

Should include:

X-Robots-Tag: noindex, nofollow

X-Robots-Tag: noindex, nofollow

undefined
undefined

Testing Authentication

测试身份认证

Test Unauthenticated Access

测试未认证访问

bash
undefined
bash
undefined

Try to access protected API without auth

Try to access protected API without auth

Expected: 401 Unauthorized

Expected: 401 Unauthorized

{

{

"error": "Unauthorized",

"error": "Unauthorized",

"message": "Authentication required"

"message": "Authentication required"

}

}

undefined
undefined

Test Authenticated Access

测试已认证访问

bash
undefined
bash
undefined

With valid Clerk session cookie

With valid Clerk session cookie

curl http://localhost:3000/api/protected-endpoint
-H "Cookie: __session=<clerk-session-token>"
curl http://localhost:3000/api/protected-endpoint
-H "Cookie: __session=<clerk-session-token>"

Expected: 200 OK (with authorized response)

Expected: 200 OK (with authorized response)

undefined
undefined

Test Authorization (Resource Ownership)

测试授权(资源归属校验)

bash
undefined
bash
undefined

Try to access another user's resource

Try to access another user's resource

curl http://localhost:3000/api/posts/user-abc-post-123
-H "Cookie: __session=<different-user-token>"
curl http://localhost:3000/api/posts/user-abc-post-123
-H "Cookie: __session=<different-user-token>"

Expected: 403 Forbidden

Expected: 403 Forbidden

{

{

"error": "Forbidden",

"error": "Forbidden",

"message": "You do not have access to this resource"

"message": "You do not have access to this resource"

}

}

undefined
undefined

Test Subscription Gating

测试订阅权限控制

bash
undefined
bash
undefined

Try premium feature with free account

Try premium feature with free account

curl http://localhost:3000/api/premium/generate
-H "Cookie: __session=<free-user-token>"
curl http://localhost:3000/api/premium/generate
-H "Cookie: __session=<free-user-token>"

Expected: 403 Forbidden

Expected: 403 Forbidden

{

{

"error": "Forbidden",

"error": "Forbidden",

"message": "Premium subscription required"

"message": "Premium subscription required"

}

}

undefined
undefined

Testing Error Handling

测试错误处理

Test Production Error Messages

测试生产环境错误信息

bash
undefined
bash
undefined

Set NODE_ENV=production temporarily

Set NODE_ENV=production temporarily

export NODE_ENV=production
export NODE_ENV=production

Trigger error in API

Trigger error in API

Expected: Generic message (no stack trace)

Expected: Generic message (no stack trace)

{

{

"error": "Internal server error",

"error": "Internal server error",

"message": "An unexpected error occurred"

"message": "An unexpected error occurred"

}

}

undefined
undefined

Test Development Error Messages

测试开发环境错误信息

bash
undefined
bash
undefined

In development (NODE_ENV=development)

In development (NODE_ENV=development)

Expected: Detailed error with stack trace

Expected: Detailed error with stack trace

{

{

"error": "Internal server error",

"error": "Internal server error",

"message": "Specific error message",

"message": "Specific error message",

"stack": "Error: ...\n at ...",

"stack": "Error: ...\n at ...",

"context": "error-test"

"context": "error-test"

}

}

undefined
undefined

Testing Dependency Security

测试依赖安全

Run npm Audit

运行npm Audit

bash
undefined
bash
undefined

Check for vulnerabilities

Check for vulnerabilities

npm audit
npm audit

Expected: 0 vulnerabilities

Expected: 0 vulnerabilities

found 0 vulnerabilities

found 0 vulnerabilities

undefined
undefined

Run Production Audit

运行生产环境审计

bash
undefined
bash
undefined

Only check production dependencies

Only check production dependencies

npm audit --production
npm audit --production

Expected: 0 vulnerabilities

Expected: 0 vulnerabilities

undefined
undefined

Check Outdated Packages

检查过期包

bash
npm outdated
bash
npm outdated

Expected: All packages up-to-date

Expected: All packages up-to-date

(or list of safe minor/patch updates available)

(or list of safe minor/patch updates available)

undefined
undefined

Run Security Check Script

运行安全检查脚本

bash
bash scripts/security-check.sh
bash
bash scripts/security-check.sh

Expected:

Expected:

- 0 vulnerabilities

- 0 vulnerabilities

- Minimal outdated packages

- Minimal outdated packages

- Fix commands if needed

- Fix commands if needed

undefined
undefined

Online Security Testing Tools

在线安全测试工具

Security Headers Scanner

Security Headers扫描器

How to use:
  1. Deploy your app
  2. Enter URL in Security Headers scanner
  3. Check for A+ rating
What it checks:
  • Content-Security-Policy
  • X-Frame-Options
  • X-Content-Type-Options
  • Strict-Transport-Security
  • Referrer-Policy
  • Permissions-Policy
使用方法:
  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

Mozilla Observatory

How to use:
  1. Enter your deployed URL
  2. Run scan
  3. Check score (aim for A+)
What it checks:
  • Security headers
  • Cookie security
  • HTTPS configuration
  • Subresource integrity
  • Content Security Policy
使用方法:
  1. 输入你部署后的应用URL
  2. 运行扫描
  3. 检查得分(目标为A+)
检测内容:
  • 安全头
  • Cookie安全
  • HTTPS配置
  • 子资源完整性
  • 内容安全策略

SSL Labs

SSL Labs

How to use:
  1. Enter your domain
  2. Wait for scan (takes ~2 minutes)
  3. Check for A+ rating
What it checks:
  • SSL/TLS configuration
  • Certificate validity
  • Protocol support
  • Cipher suite strength
  • HSTS configuration
使用方法:
  1. 输入你的域名
  2. 等待扫描完成(约2分钟)
  3. 检查是否获得A+评级
检测内容:
  • SSL/TLS配置
  • 证书有效性
  • 协议支持
  • 加密套件强度
  • HSTS配置

Pre-Deployment Security Checklist

部署前安全检查清单

Run through this checklist before every production deployment:
每次生产环境部署前都要完成以下检查项:

Environment & Configuration

环境与配置

  • All environment variables set in production
  • CSRF_SECRET
    generated and configured (32+ bytes)
  • SESSION_SECRET
    generated and configured (32+ bytes)
  • Clerk production keys configured
  • Stripe live mode keys configured (if using payments)
  • .env.local
    NOT committed to git
  • 生产环境所有环境变量已配置
  • 已生成并配置
    CSRF_SECRET
    (32字节以上)
  • 已生成并配置
    SESSION_SECRET
    (32字节以上)
  • Clerk生产密钥已配置
  • Stripe live模式密钥已配置(若使用支付功能)
  • .env.local
    未提交到git

Dependencies

依赖项

  • Run
    npm audit --production
    - 0 vulnerabilities
  • Run
    npm outdated
    - Check for critical updates
  • package-lock.json
    committed
  • Next.js on latest stable version
  • 运行
    npm audit --production
    - 0个漏洞
  • 运行
    npm outdated
    - 检查是否有重要更新
  • package-lock.json
    已提交
  • Next.js为最新稳定版本

Security Features

安全功能

  • CSRF protection tested (see tests above)
  • Rate limiting tested (see tests above)
  • Input validation tested (see tests above)
  • Security headers verified (securityheaders.com)
  • HSTS enabled in production
  • Error messages are generic in production
  • CSRF防护已测试(参考上述测试用例)
  • 速率限制已测试(参考上述测试用例)
  • 输入验证已测试(参考上述测试用例)
  • 安全头已通过securityheaders.com验证
  • 生产环境已开启HSTS
  • 生产环境错误信息为通用提示

Authentication & Authorization

身份认证与授权

  • Protected routes require authentication
  • Resource ownership checked before access
  • Subscription status verified for premium features
  • Webhook signatures verified (Clerk, Stripe)
  • Session expiration handled gracefully
  • 受保护路由需要身份认证
  • 访问资源前已校验归属权
  • 高级功能已验证订阅状态
  • Webhook签名已校验(Clerk、Stripe)
  • 会话过期处理逻辑正常

API Security

API安全

  • All POST/PUT/DELETE routes have CSRF protection
  • All public endpoints have rate limiting
  • All user input validated with Zod
  • All errors handled with error handler utilities
  • No sensitive data in logs
  • No hardcoded secrets in code
  • 所有POST/PUT/DELETE路由都有CSRF防护
  • 所有公开端点都有速率限制
  • 所有用户输入都通过Zod验证
  • 所有错误都通过错误处理工具处理
  • 日志中无敏感数据
  • 代码中无硬编码密钥

Payment Security (if applicable)

支付安全(若适用)

  • Using Clerk Billing + Stripe (not handling cards directly)
  • Webhooks verified (Svix signatures)
  • Subscription status checked on server
  • Test mode disabled in production
  • 使用Clerk Billing + Stripe(不直接处理银行卡信息)
  • Webhook已验证(Svix签名)
  • 服务端已校验订阅状态
  • 生产环境已关闭测试模式

Testing

测试

  • Run rate limit test:
    node scripts/test-rate-limit.js
  • Test CSRF protection manually
  • Test input validation with malicious input
  • Check security headers:
    curl -I https://yourapp.com
  • Test authentication flows
  • Test error handling in production mode
  • 运行速率限制测试:
    node scripts/test-rate-limit.js
  • 手动测试CSRF防护
  • 用恶意输入测试输入验证
  • 检查安全头:
    curl -I https://yourapp.com
  • 测试身份认证流程
  • 测试生产模式下的错误处理

Monitoring

监控

  • Error logging configured (Vercel logs)
  • Failed auth attempts tracked (Clerk dashboard)
  • GitHub Dependabot alerts enabled
  • Security headers monitored (automated checks)
  • 已配置错误日志(Vercel日志)
  • 已跟踪失败的认证尝试(Clerk控制台)
  • 已开启GitHub Dependabot告警
  • 已配置安全头自动监控

Automated Testing Script

自动化测试脚本

security-test.sh

security-test.sh

Create a comprehensive test script:
bash
#!/bin/bash

echo "================================="
echo "Security Testing Suite"
echo "================================="
echo ""
创建一个完整的测试脚本:
bash
#!/bin/bash

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

Color codes

Color codes

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

Test counter

Test counter

PASSED=0 FAILED=0
PASSED=0 FAILED=0

Function to run test

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

**Run it:**
```bash
bash scripts/security-test.sh
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
bash scripts/security-test.sh

Continuous Security Testing

持续安全测试

Add to CI/CD Pipeline

添加到CI/CD流水线

yaml
undefined
yaml
undefined

.github/workflows/security.yml

.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"
undefined
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"
undefined

Manual Penetration Testing

手动渗透测试

Test XSS in All Input Fields

测试所有输入字段的XSS漏洞

  1. Try these payloads in every input:
    <script>alert('XSS')</script>
    <img src=x onerror=alert('XSS')>
    <svg onload=alert('XSS')>
    javascript:alert('XSS')
    "><script>alert('XSS')</script>
  2. Verify all are sanitized
  1. 在每个输入框中尝试以下 payload:
    <script>alert('XSS')</script>
    <img src=x onerror=alert('XSS')>
    <svg onload=alert('XSS')>
    javascript:alert('XSS')
    "><script>alert('XSS')</script>
  2. 验证所有payload都被清理

Test SQL Injection

测试SQL注入

  1. Try these in search/query fields:
    ' OR '1'='1
    '; DROP TABLE users; --
    ' UNION SELECT * FROM users --
  2. Verify input validation blocks or sanitizes
  1. 在搜索/查询字段中尝试以下内容:
    ' OR '1'='1
    '; DROP TABLE users; --
    ' UNION SELECT * FROM users --
  2. 验证输入验证会拦截或清理这些内容

Test CSRF

测试CSRF

  1. Create malicious HTML file:
    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. Open while logged in
  3. Verify request blocked (403 Forbidden)
  1. 创建恶意HTML文件:
    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)

Test Authorization

测试授权

  1. Create resource as User A
  2. Try to access/modify as User B
  3. Verify 403 Forbidden
  1. 用用户A创建资源
  2. 尝试用用户B访问/修改该资源
  3. 验证返回403 Forbidden

What To Monitor Post-Deployment

部署后需要监控的内容

Daily

每日

  • Error rates (Vercel dashboard)
  • Failed authentication attempts (Clerk dashboard)
  • Rate limit violations (check logs for 429 responses)
  • 错误率(Vercel控制台)
  • 失败的身份认证尝试(Clerk控制台)
  • 速率限制违规情况(查看日志中的429响应)

Weekly

每周

  • Run
    npm audit --production
  • Check GitHub Dependabot alerts
  • Review error logs for patterns
  • 运行
    npm audit --production
  • 检查GitHub Dependabot告警
  • 复盘错误日志中的规律

Monthly

每月

  • Full security audit
  • Update dependencies
  • Re-run security testing suite
  • Check security headers (securityheaders.com)
  • 完整安全审计
  • 更新依赖
  • 重新运行完整安全测试套件
  • 检查安全头(securityheaders.com)

References

参考资料

Next Steps

后续步骤

  • For fixing issues: Use appropriate security skill (csrf-protection, rate-limiting, etc.)
  • For deployment: Complete pre-deployment checklist above
  • For monitoring: Set up automated security scans in CI/CD
  • For ongoing maintenance: Run monthly security audit
  • 问题修复:使用对应的安全技能(csrf-protection、rate-limiting等)
  • 部署:完成上述部署前检查清单
  • 监控:在CI/CD中配置自动化安全扫描
  • 日常维护:每月运行一次完整安全审计