Security Fundamentals

Web Security Essentials

Learn the security mindset and the essential protections every web application must have.

The Security Mindset

Security starts with a fundamental shift in perspective: assume everything from the client is malicious. Every URL parameter, form field, cookie value, and API request could be crafted by an attacker specifically to exploit your application.

This is not paranoia — it is engineering discipline. Defense requires anticipating attacks.

The CIA Triad

All of information security is built on three principles:

Confidentiality — Data is only seen by authorized users. Your users' passwords, credit cards, and personal information must be protected from unauthorized access.

Integrity — Data is not modified without authorization. Database records, file uploads, and API responses must arrive unmodified and come from legitimate sources.

Availability — The system is accessible when needed. Your application must continue to serve legitimate users even under attack (DDoS resistance, rate limiting, graceful degradation).

HTTPS: Non-Negotiable

HTTP transmits data in plain text. Anyone on the same network — a coffee shop WiFi, an ISP, a government router — can read every request and response. HTTPS encrypts the connection using TLS.

HTTPS is mandatory because:

  • Protects user credentials and sensitive data in transit
  • Required for modern browser features (Service Workers, geolocation, camera access)
  • Required for HTTP/2 (significantly faster than HTTP/1.1)
  • Ranked higher in Google search results
  • Users see "Not Secure" warnings in the address bar without it

CORS: Cross-Origin Resource Sharing

Same-origin policy prevents JavaScript on one domain from making requests to a different domain by default. CORS is the mechanism that explicitly relaxes this restriction.

Misconfigured CORS is a common vulnerability. Never do this:

typescript
// DANGEROUS — allows any origin to make requests
res.setHeader('Access-Control-Allow-Origin', '*');

Instead, explicitly allowlist trusted origins:

typescript
const allowedOrigins = ['https://yourapp.com', 'https://staging.yourapp.com'];
const origin = req.headers.origin;

if (allowedOrigins.includes(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin);
}

Security Headers

HTTP response headers instruct the browser how to behave. These six headers form the foundation of web security:

typescript
// Next.js middleware to set security headers
export function middleware(request: NextRequest) {
  const response = NextResponse.next();

  response.headers.set('X-Frame-Options', 'DENY');
  response.headers.set('X-Content-Type-Options', 'nosniff');
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
  response.headers.set(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
  );

  return response;
}

Cookie Security

Cookies that store session tokens or authentication state need three attributes:

typescript
res.setHeader('Set-Cookie', [
  'sessionToken=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600'
]);
  • HttpOnly — Prevents JavaScript from reading the cookie (XSS protection)
  • Secure — Only sent over HTTPS connections
  • SameSite=Strict — Not sent with cross-site requests (CSRF protection)

Defense in Depth

Never rely on a single security control. Layer multiple protections so that if one fails, others catch the attack.

Example: Protecting an API endpoint:

  1. HTTPS (transit encryption)
  2. Authentication token validation
  3. Rate limiting (prevents brute force)
  4. Input validation (prevents injection)
  5. Database parameterized queries (prevents SQL injection even if input validation fails)
  6. Error messages that don't leak internal details

Key Takeaways

  • Assume all client input is malicious — validate everything on the server
  • HTTPS is mandatory — there is no valid reason to use HTTP for any production application
  • Misconfigured CORS is a vulnerability — explicitly allowlist trusted origins, never use wildcard for sensitive endpoints
  • Six security headers form the baseline: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
  • Defense in depth: layer multiple protections rather than relying on any single control

Example

typescript
// Next.js middleware: security headers
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const response = NextResponse.next();

  response.headers.set('X-Frame-Options', 'DENY');
  response.headers.set('X-Content-Type-Options', 'nosniff');
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  response.headers.set(
    'Strict-Transport-Security',
    'max-age=31536000; includeSubDomains; preload'
  );
  response.headers.set(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
  );

  return response;
}
Try it yourself — TYPESCRIPT

Docker, AWS, Vercel, Netlify, GitHub, GitHub Actions are trademarks of Docker, Inc., Amazon.com, Inc., Vercel, Inc., Netlify, Inc., Microsoft Corporation. DevForge Academy is not affiliated with, endorsed by, or sponsored by these companies. Referenced for educational purposes only. See full disclaimers