security-hardening-checklist
Security Hardening Checklist
To perform a comprehensive security audit and generate hardening recommendations, follow these steps systematically.
Step 1: Project Discovery
Identify the project structure and tech stack:
-
Use Glob to find key files:
package.json- Dependencies and scriptsnext.config.*- Next.js configurationmiddleware.ts- Middleware setupapp/**/*.{ts,tsx}- Application routes.env.example- Environment variables
-
Identify authentication provider (Supabase, NextAuth, Clerk, etc.)
-
Identify database type (PostgreSQL, MySQL, MongoDB, etc.)
-
Check for security libraries (helmet, rate-limit, etc.)
Step 2: Security Headers Audit
Check for security headers configuration.
Check Next.js Config
Use Grep to search for security headers in next.config.js/ts:
- "X-Frame-Options"
- "X-Content-Type-Options"
- "X-XSS-Protection"
- "Strict-Transport-Security"
- "Content-Security-Policy"
- "Referrer-Policy"
- "Permissions-Policy"
Generate Missing Headers
Consult references/security-headers.md and create configuration:
// next.config.ts
const securityHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'X-XSS-Protection',
value: '1; mode=block'
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin'
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()'
}
]
const nextConfig = {
async headers() {
return [
{
source: '/:path*',
headers: securityHeaders,
},
]
},
}
Step 3: Cookie Security Audit
Check cookie configuration for auth and session management.
Check for Insecure Cookie Settings
Use Grep to search for cookie operations:
- "setCookie"
- "cookies().set"
- "document.cookie"
- "res.cookie"
Review Cookie Security Attributes
Check for:
httpOnly: true- Prevents JavaScript accesssecure: true- HTTPS onlysameSite: 'strict'or'lax'- CSRF protection- Proper expiration times
Generate Secure Cookie Helper
// lib/cookies.ts
import { cookies } from 'next/headers'
export function setSecureCookie(
name: string,
value: string,
maxAge: number = 3600
) {
cookies().set(name, value, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge,
path: '/',
})
}
Step 4: RLS Policy Audit
For Supabase/PostgreSQL projects, audit Row-Level Security.
Check RLS Status
Search for migration files or schema files:
-- Check if RLS is enabled
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
Identify Tables Without RLS
Use Grep to find table definitions and check which lack RLS policies.
Flag Security Gaps
- Tables with user data but no RLS
- Tables with RLS but no policies
- Policies that may be too permissive
- Missing WITH CHECK clauses
Consult references/rls-checklist.md for comprehensive checks.
Step 5: Input Sanitization Audit
Check for unsafe input handling.
Search for Direct Database Queries
Use Grep to find potential SQL injection risks:
- "`.query(`"
- "`${" (template literals in queries)
- "raw("
Check Form Input Validation
Search for form handlers without validation:
- "formData.get("
- "request.json()"
- "params."
Validate Zod Usage
Check if forms use Zod or similar validation:
- "z.object"
- "safeParse"
- "parse"
Generate Validation Examples
// lib/validations/common.ts
import { z } from 'zod'
// Sanitize HTML input
export const sanitizeHtml = (input: string): string => {
return input
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/')
}
// Common validation schemas
export const emailSchema = z.string().email()
export const urlSchema = z.string().url()
export const uuidSchema = z.string().uuid()
export const slugSchema = z.string().regex(/^[a-z0-9-]+$/)
Step 6: Rate Limiting Audit
Check for rate limiting on API routes and actions.
Check for Rate Limiting Libraries
Search package.json for:
@upstash/ratelimitexpress-rate-limitrate-limiter-flexible
Identify Unprotected Endpoints
Use Glob to find all API routes:
app/api/**/route.ts
Search each for rate limiting code.
Generate Rate Limiting Implementation
// lib/rate-limit.ts
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'
export const authRateLimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(5, '1 m'),
prefix: 'ratelimit:auth',
})
export const apiRateLimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(100, '1 m'),
prefix: 'ratelimit:api',
})
// Usage in API route
export async function POST(request: Request) {
const ip = request.headers.get('x-forwarded-for') ?? 'unknown'
const { success } = await authRateLimit.limit(ip)
if (!success) {
return new Response('Rate limit exceeded', { status: 429 })
}
// Handle request
}
Step 7: Environment Variables Audit
Check for exposed secrets and proper env var handling.
Check .env.example
Verify sensitive variables are not committed:
- Database URLs with credentials
- API keys
- JWT secrets
Search for Hardcoded Secrets
Use Grep to find potential hardcoded secrets:
- "password.*=.*['\"]"
- "secret.*=.*['\"]"
- "api[-_]?key.*=.*['\"]"
- "token.*=.*['\"]"
Check Client-Side Exposure
Search for env vars used in client components:
- "process.env" in files with "use client"
Only NEXT_PUBLIC_* vars should be in client code.
Step 8: HTTPS and Transport Security
Verify HTTPS is enforced.
Check for HTTP Links
Use Grep to find insecure URLs:
- "http://" (not in comments)
Check Middleware for HTTPS Redirect
Look for HTTPS enforcement in middleware.
Generate HTTPS Enforcement
// middleware.ts
export function middleware(request: NextRequest) {
// Enforce HTTPS in production
if (
process.env.NODE_ENV === 'production' &&
request.headers.get('x-forwarded-proto') !== 'https'
) {
return NextResponse.redirect(
`https://${request.headers.get('host')}${request.nextUrl.pathname}`,
301
)
}
// Other middleware logic
}
Step 9: CORS Configuration Audit
Check CORS configuration for API routes.
Search for CORS Headers
Use Grep to find CORS configuration:
- "Access-Control-Allow-Origin"
- "cors("
Verify CORS is Not Too Permissive
Flag Access-Control-Allow-Origin: * in production.
Generate Proper CORS Configuration
// lib/cors.ts
export function setCorsHeaders(
response: NextResponse,
allowedOrigins: string[]
) {
const origin = request.headers.get('origin')
if (origin && allowedOrigins.includes(origin)) {
response.headers.set('Access-Control-Allow-Origin', origin)
response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
response.headers.set('Access-Control-Max-Age', '86400')
}
return response
}
Step 10: Dependency Security Audit
Check for vulnerable dependencies.
Run npm audit
npm audit --json
Check for Outdated Packages
npm outdated
Flag Critical Vulnerabilities
Identify packages with known security issues.
Step 11: Generate Security Report
Create comprehensive security audit report using template from assets/security-report-template.md:
# Security Audit Report
**Generated**: [timestamp]
**Project**: [project name]
## Executive Summary
**Overall Security Score**: X/100
- Critical Issues: X
- High Priority: X
- Medium Priority: X
- Low Priority: X
## Critical Issues (Fix Immediately)
### 1. Missing Security Headers
**Severity**: Critical
**Impact**: Application vulnerable to XSS, clickjacking
**Fix**: Add security headers to next.config.ts
### 2. No Rate Limiting on Auth Endpoints
**Severity**: Critical
**Impact**: Vulnerable to brute force attacks
**Fix**: Implement rate limiting
[Continue for all issues...]
## Recommendations
1. Security Headers
2. Cookie Security
3. RLS Policies
4. Input Validation
5. Rate Limiting
6. HTTPS Enforcement
7. Environment Variables
8. Dependency Updates
## Implementation Checklist
- [ ] Add security headers
- [ ] Configure secure cookies
- [ ] Enable RLS on all tables
- [ ] Add input validation
- [ ] Implement rate limiting
- [ ] Enforce HTTPS
- [ ] Audit environment variables
- [ ] Update vulnerable dependencies
Step 12: Generate Fix Scripts
Create scripts to automate security improvements:
// scripts/add-security-headers.ts
// Automatically adds security headers to next.config
# scripts/enable-rls.sql
# SQL script to enable RLS on all tables
Consulting References
Throughout audit:
- Consult
references/security-headers.mdfor header configuration - Consult
references/rls-checklist.mdfor database security - Consult
references/owasp-top-10.mdfor common vulnerabilities - Use templates from
assets/security-report-template.md
Output Format
Generate files:
reports/
security-audit-[timestamp].md
fixes/
security-headers.ts
rate-limiting.ts
input-validation.ts
scripts/
enable-rls.sql
fix-cookies.ts
Verification Checklist
Before completing audit:
- All routes analyzed
- Security headers reviewed
- Cookie configuration checked
- RLS policies audited
- Input validation verified
- Rate limiting assessed
- Environment variables checked
- Dependencies scanned
- HTTPS enforcement verified
- CORS configuration reviewed
Completion
When finished:
- Display security score
- Highlight critical issues
- Provide prioritized recommendations
- Offer to implement fixes
- Generate implementation scripts