Claude
Skills
Sign in
Back

security-testing-verification

Included with Lifetime
$97 forever

Test security features and verify implementation before deployment. Use this skill when you need to test CSRF protection, rate limiting, input validation, verify security headers, run security audits, or check the pre-deployment security checklist. Triggers include "test security", "security testing", "verify security", "security checklist", "pre-deployment", "test CSRF", "test rate limit", "security verification".

Security

What this skill does


# 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
# 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!
```

### Manual Testing

```bash
# 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
```

### Test Reset After Window

```bash
# 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)
```

## Testing CSRF Protection

### Test 1: Request Without Token (Should Fail)

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

# Expected: 403 Forbidden
# {
#   "error": "CSRF token missing"
# }
```

### Test 2: Request With Valid Token (Should Succeed)

```bash
# 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
```

### Test 3: Token Reuse (Should Fail)

```bash
# 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
```

### Test 4: Invalid Token (Should Fail)

```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
# {
#   "error": "CSRF token invalid"
# }
```

## Testing Input Validation

### Test XSS Sanitization

```bash
# 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 Length Validation

```bash
# 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)"
#   }
# }
```

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

# Expected: 400 Bad Request
# {
#   "error": "Validation failed",
#   "details": {
#     "email": "Invalid email"
#   }
# }
```

### Test Required Fields

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

## Testing Security Headers

### Test All Headers

```bash
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)
```

### Test CSP

```bash
# 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
```

### Test HSTS (Production Only)

```bash
# In production environment
curl -I https://yourapp.com | grep "Strict-Transport-Security"

# Should return:
# Strict-Transport-Security: max-age=31536000; includeSubDomains
```

### Test Protected Route Headers

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

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

## Testing Authentication

### Test Unauthenticated Access

```bash
# Try to access protected API without auth
curl http://localhost:3000/api/protected-endpoint

# Expected: 401 Unauthorized
# {
#   "error": "Unauthorized",
#   "message": "Authentication required"
# }
```

### Test Authenticated Access

```bash
# With valid Clerk session cookie
curl http://localhost:3000/api/protected-endpoint \
  -H "Cookie: __session=<clerk-session-token>"

# Expected: 200 OK (with authorized response)
```

### Test Authorization (Resource Ownership)

```bash
# 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"
# }
```

### Test Subscription Gating

```bash
# 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"
# }
```

## Testing Error Handling

### Test Production Error Messages

```bash
# 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"
# }
```

### Test Development Error Messages

```bash
# 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"
# }
```

## Testing Dependency Security

### Run npm Audit

```bash
# Check for vulnerabilities
npm audit

# Expected: 0 vulnerabilities
# found 0 vulnerabilities
```

### Run Production Audit

```bash
# Only check production dependencies
npm audit --production

# Expected: 0 vulnerabilities
```

### Check Outdated Packages

```bash
npm outdated

# Expected: All packages up-to-date
# (or list of safe minor/patch updates available)
```

### Run Security Check Script

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

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

## Online Security Testing Tools

### Security Headers Scanner

**Tool:** https://securityheaders.com/

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

### Mozilla Observatory

**Tool:** htt
Files: 1
Size: 15.5 KB
Complexity: 22/100
Category: Security

Related in Security