Documentation

Security Features

Built-in security features included in ShipSecure boilerplate.

Built-in Security Features

ShipSecure comes with enterprise-grade security features, all tested with TDD. These features are already configured and work out of the box.

Security Headers

Automatically applied to all responses via middleware:

  • Content-Security-Policy: Prevents XSS attacks
  • Strict-Transport-Security: Forces HTTPS
  • X-Frame-Options: Prevents clickjacking
  • X-Content-Type-Options: Prevents MIME sniffing
  • Referrer-Policy: Controls referrer information
  • Permissions-Policy: Restricts browser features

Location: src/lib/security/headers.ts
Tests: src/lib/security/__tests__/headers.test.ts

Rate Limiting

Smart rate limiting with Upstash Redis support:

  • API Routes: 60 requests per minute per IP
  • Auth Routes: 20 requests per minute per IP (stricter to prevent brute force)
  • In-memory fallback: Works without Redis in development
  • Configurable: Adjust limits in src/middleware.ts

Location: src/lib/security/rate-limit.ts
Tests: src/lib/security/__tests__/rate-limit.test.ts

How it works:

// Example: Rate limit configuration in middleware.ts
export const config = {
  matcher: [
    "/api/:path*", // 60 requests/minute
    "/api/auth/:path*", // 20 requests/minute (stricter)
  ],
};

Production setup:

  • Configure UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN for production
  • Without Redis, rate limiting uses in-memory storage (less effective on serverless)
  • Free tier available at Upstash (10,000 requests/day)

Input Validation

Type-safe validation with Zod:

  • All API inputs validated with Zod schemas
  • Automatic error formatting
  • Type-safe request/response handling

Location: src/lib/security/validation.ts

Example usage:

import { z } from "zod";
import { validateRequest } from "@/lib/security/validation";

// Define your schema
const createUserSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(18).max(120),
});

// Use in API route
export async function POST(request: Request) {
  const { data, error } = await validateRequest(request, createUserSchema);

  if (error) {
    return NextResponse.json({ error }, { status: 400 });
  }

  // data is now type-safe and validated
  // Proceed with your logic...
}

Benefits:

  • Prevents invalid data from reaching your database
  • TypeScript types generated automatically from schemas
  • Clear error messages for API consumers

Authentication

Secure authentication with Auth.js v5:

  • GitHub & Google OAuth: Pre-configured
  • CSRF Protection: Built-in
  • Secure Sessions: HTTP-only cookies
  • Database Sessions: Stored securely in PostgreSQL

Pre-Deployment Checklist

Before deploying to production, verify these essential configurations. For detailed deployment instructions, see the Deployment Guide.

Quick checklist:

  • AUTH_SECRET is set (generate with npx auth secret)
  • DATABASE_URL points to your production database
  • OAuth credentials are configured
  • OAuth callback URLs updated in provider settings
  • Database migrations run (npx prisma migrate deploy)
  • Optional: Upstash Redis configured for production rate limiting

Verification

Test that security headers are working after deployment:

# Test your production site (replace with your actual domain)
curl -I https://your-domain.com

Expected output: You should see these security headers in the response:

content-security-policy: default-src 'self'; ...
strict-transport-security: max-age=31536000; includeSubDomains
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(), camera=()

What to check:

  • All headers are present
  • x-frame-options is set to DENY
  • strict-transport-security includes max-age
  • content-security-policy is configured

If headers are missing:

  • Check that middleware is running: src/middleware.ts
  • Verify deployment includes all files
  • Check hosting platform settings (some platforms strip headers)

Protected Against Common Vulnerabilities

ShipSecure includes built-in protection against common security threats:

SQL Injection

Protection: Prisma ORM uses parameterized queries

// Prisma automatically escapes user input
const user = await db.user.findUnique({
  where: { email: userInput }, // Safe - Prisma handles escaping
});

XSS (Cross-Site Scripting)

Protection:

  • Content-Security-Policy headers restrict script execution
  • React automatically escapes user input in JSX
// React escapes automatically
<div>{userInput}</div> // Safe - React escapes HTML

CSRF (Cross-Site Request Forgery)

Protection: Auth.js v5 includes built-in CSRF tokens

  • All authentication requests include CSRF tokens
  • Tokens are validated automatically

Clickjacking

Protection: X-Frame-Options: DENY header

  • Prevents your site from being embedded in iframes
  • Configured in src/lib/security/headers.ts

MIME Sniffing

Protection: X-Content-Type-Options: nosniff header

  • Prevents browsers from guessing content types
  • Forces browsers to respect declared content types

DDoS/Brute Force

Protection: Rate limiting middleware

  • API routes: 60 requests/minute per IP
  • Auth routes: 20 requests/minute per IP
  • Configurable in src/middleware.ts

Regular Maintenance

Keep your application secure with regular maintenance:

Check for Vulnerabilities

# Check for known vulnerabilities in dependencies
npm audit

# Fix automatically fixable issues
npm audit fix

# For breaking changes, review manually
npm audit fix --force  # Use with caution

Update Dependencies

# Check for outdated packages
npm outdated

# Update all packages (review changes first)
npm update

# Or update specific packages
npm install package-name@latest

Security Checklist

Monthly:

  • Run npm audit and fix vulnerabilities
  • Review and rotate API keys (OAuth secrets, database passwords)
  • Check security headers are still working: curl -I https://your-domain.com

Quarterly:

  • Update dependencies to latest stable versions
  • Review access logs for suspicious activity
  • Test authentication flows still work after updates

After Security Incidents:

  • Rotate all secrets immediately
  • Review access logs
  • Update affected dependencies
  • Consider adding additional rate limiting if needed

That's it! The security features are already built-in and tested. Just configure your environment variables and you're ready to deploy securely.

Next Steps