Web Security Essentials
HTTPS, CSRF, XSS, SQL injection: defense-in-depth strategies
Security · 3 min readSecurity is not a feature—it's infrastructure. Cover the essentials: HTTPS, CSRF tokens, XSS prevention, input validation, and SQL injection protection.
Layer 1: Transport Security (HTTPS)
// Always redirect HTTP to HTTPS
export async function middleware(request: Request) {
const { protocol, host } = new URL(request.url);
if (protocol === "http:") {
return Response.redirect(`https://${host}${request.url}`, 308);
}
return NextResponse.next();
}
// Enforce HSTS (HTTP Strict Transport Security)
export async function middleware(request: Request) {
const response = NextResponse.next();
response.headers.set(
"Strict-Transport-Security",
"max-age=31536000; includeSubDomains; preload"
);
return response;
}Layer 2: CSRF Protection
import { cookies } from "next/headers";
import crypto from "crypto";
// Generate and store CSRF token
export async function getCSRFToken() {
const token = crypto.randomBytes(32).toString("hex");
const store = await cookies();
store.set("csrf_token", token, { httpOnly: true, secure: true });
return token;
}
// Validate on form submission
export async function validateCSRF(req: Request) {
const formToken = (await req.formData()).get("csrf_token");
const store = await cookies();
const cookieToken = store.get("csrf_token")?.value;
if (!formToken || formToken !== cookieToken) {
throw new Error("CSRF token mismatch");
}
}Layer 3: XSS Prevention
// ❌ Vulnerable: user input rendered as HTML
export function UserProfile({ bio }) {
return <div dangerouslySetInnerHTML={{ __html: bio }} />;
}
// ✅ Safe: React escapes by default
export function UserProfile({ bio }) {
return <div>{bio}</div>; // HTML entities escaped
}
// ✅ Safe: sanitize if HTML needed
import DOMPurify from "dompurify";
export function UserBio({ html }) {
const clean = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}Layer 4: SQL Injection Prevention
// ❌ Vulnerable: string concatenation
const result = await db.query(`SELECT * FROM users WHERE email = '${email}'`);
// ✅ Safe: parameterized queries
const result = await db.query("SELECT * FROM users WHERE email = $1", [email]);
// ✅ Safe: ORM with built-in escaping
const user = await User.where({ email }).first();Layer 5: Content Security Policy (CSP)
// Restrict what resources can be loaded
export async function middleware(request: Request) {
const response = NextResponse.next();
response.headers.set(
"Content-Security-Policy",
[
"default-src 'self'", // Only from origin
"script-src 'self' cdn.example.com", // Scripts from specific domains
"style-src 'self' 'unsafe-inline'", // Styles (inline OK for dev)
"img-src 'self' data: https:", // Images from origin or HTTPS
"connect-src 'self' api.example.com", // API calls allowed
"frame-ancestors 'none'", // Can't be embedded
].join("; ")
);
return response;
}Security Checklist
- [x] Force HTTPS everywhere with HSTS.
- [x] Implement CSRF tokens on all state-changing operations.
- [x] Escape user input before rendering (React does this by default).
- [x] Use parameterized SQL queries; never concatenate.
- [x] Set secure, httpOnly, sameSite cookies.
- [x] Implement Content-Security-Policy header.
- [ ] Add rate limiting on login/password endpoints.
- [ ] Enable 2FA for sensitive accounts.
Common Vulnerabilities
| Vulnerability | Prevention | | --------------------------------- | --------------------------------------------- | | XSS | Escape output, sanitize HTML, CSP | | CSRF | CSRF tokens, SameSite cookies | | SQL Injection | Parameterized queries, ORMs | | Insecure Direct Object References | Check authorization before DB query | | Sensitive Data Exposure | HTTPS, no logs of secrets, encryption at rest |
Results
- Zero XSS vulnerabilities in security audit.
- CSRF token validation blocks all token-hijacking attempts.
- Dependency vulnerabilities caught by scanning tools (npm audit).
Tools
- OWASP Top 10: reference for critical risks.
- npm audit: scan dependencies for vulnerabilities.
- Burp Suite: penetration testing.
Next
- Implement rate limiting on authentication endpoints.
- Add API key management and rotation.