web-security-cheatsheet

The Complete Guide to Understanding Modern Web Security Mechanisms

A comprehensive, practical guide that explains not just what these security features do, but why they exist, how they work together, and when to use each one.


Table of Contents


The Big Picture: Why These Exist

The Web Security Problem

Imagine you're visiting yourbank.com. On the same browser, you also have evil-site.com open in another tab. Without security mechanisms:

The solution? A layered defense system:

Quick Comparison: At a Glance

Feature
What It Controls
Enforced By
Use Case

SOP

Which origins can access your data

Browser (automatic)

Fundamental isolation

CORS

Which origins you ALLOW to access data

Server (you configure)

API sharing

CSP

What content can load/execute

Server + Browser

XSS prevention

HttpOnly

Whether JS can read cookies

Server (cookie flag)

Session protection


Same-Origin Policy (SOP)

The Foundation of Web Security

Think of it as: Each website lives in its own fortress. By default, they can't peek into each other's windows.

What is an "Origin"?

An origin is defined by three components:

Same Origin Examples:

What SOP Actually Does

✅ Allows (No Restrictions):

  1. Embedding resources (but not reading them):

  2. Sending requests (POST, GET, etc.):

Blocks (SOP Restrictions):

  1. Reading responses from other origins:

  2. Accessing DOM of other origins:

  3. Reading cookies/storage from other origins:

Real-World Example: Why SOP Matters

Scenario: You're logged into Facebook. You visit a malicious website.

With SOP:

Common Misconceptions

Wrong Belief
Reality

"SOP blocks sending requests"

No, it blocks reading responses

"SOP prevents CSRF"

No, requests are still sent with cookies

"Same domain = same origin"

No, protocol and port matter too

"SOP prevents all XSS"

No, XSS happens on your origin


Cross-Origin Resource Sharing (CORS)

The Controlled Bridge Between Origins

Think of it as: SOP builds walls between websites. CORS lets servers install doors in those walls, with keys for trusted visitors.

The Problem CORS Solves

Modern web apps often need to:

  • Frontend on myapp.com talks to API on api.myapp.com

  • Mobile app needs to call your server

  • Partner sites need to access your public data

Without CORS: All blocked by SOP With CORS: Server says "I trust these origins"

How CORS Works: The Complete Flow

Simple Requests (GET, POST with simple headers)

Preflight Requests (PUT, DELETE, custom headers)

Essential CORS Headers Explained

Server Response Headers

Browser Request Headers (Automatic)

Implementation Examples

Example 1: Node.js/Express - Whitelist Specific Origins

Example 2: Using CORS Middleware

Example 3: Nginx Configuration

CORS Security: Common Vulnerabilities

Vulnerability 1: Reflecting Origin Without Validation

Fix:

Vulnerability 2: Wildcard with Credentials

Vulnerability 3: Over-Permissive for Sensitive Data

Frontend: Making CORS Requests

Fetch API

XMLHttpRequest

What CORS Does NOT Protect Against


Content Security Policy (CSP)

Your Page's Bouncer: Controls What Gets In

Think of it as: A security guard at your website's door with a whitelist. Only content from approved sources gets through.

The XSS Problem CSP Solves

Cross-Site Scripting (XSS) is when attackers inject malicious code into your website:

Without CSP: Script runs, cookies stolen With CSP: Script blocked, site stays safe

CSP Directives: The Complete List

Resource Loading Directives

Directive
What It Controls
Example

default-src

Default for all resource types

'self'

script-src

JavaScript sources

'self' https://cdn.com

style-src

CSS stylesheets

'self' 'unsafe-inline'

img-src

Images

'self' data: https:

font-src

Web fonts

'self' https://fonts.gstatic.com

connect-src

AJAX, WebSocket, EventSource

'self' https://api.example.com

media-src

Audio, video (<audio>, <video>)

'self'

object-src

<object>, <embed>, <applet>

'none'

frame-src

<iframe>, <frame>

'self'

worker-src

Web Workers, Service Workers

'self'

manifest-src

Web app manifest

'self'

Document Directives

Directive
Purpose
Example

base-uri

Restricts <base> URLs

'self'

form-action

Where forms can submit

'self'

frame-ancestors

Who can embed this page (X-Frame-Options)

'none'

sandbox

Enables sandbox mode

allow-scripts allow-same-origin

Reporting Directives

Directive
Purpose

report-uri

Where to send violation reports (deprecated)

report-to

Named reporting endpoint (modern)

Source Values: The Keywords

Value
Meaning
Use Case

'none'

Block everything

Block plugins: object-src 'none'

'self'

Same origin only

Scripts from your domain

*

Any URL (except data:, blob:, filesystem:)

Very permissive (avoid)

https:

Any HTTPS URL

Require encrypted connections

data:

Data URIs (data:image/...)

Base64 encoded resources

'unsafe-inline'

Inline scripts/styles

⚠️ Weakens XSS protection

'unsafe-eval'

eval(), Function()

⚠️ Dangerous, avoid

'strict-dynamic'

Trust scripts loaded by trusted scripts

Modern XSS protection

'nonce-[random]'

Scripts with matching nonce attribute

Best for inline scripts

'sha256-[hash]'

Scripts matching hash

Static inline scripts

https://example.com

Specific domain

Trust specific CDN

*.example.com

Domain with subdomains

All subdomains

CSP Levels: From Basic to Bulletproof

Level 1: Minimal Protection

What this does:

  • ✅ Only resources from your domain

  • ❌ Blocks all inline scripts/styles

  • ❌ Blocks external CDNs

Good for: Simple websites with no external resources

Level 2: Practical Website

What this does:

  • ✅ Scripts from your domain + specific CDNs

  • ✅ Inline styles allowed (for convenience)

  • ✅ Images from any HTTPS or data URIs

  • ✅ API calls to your API domain

  • ✅ Prevents clickjacking

  • ✅ Blocks plugins (Flash, Java)

Good for: Most production websites

Level 3: Maximum Security with Nonces

What this does:

  • Maximum XSS protection

  • ✅ Only scripts with correct nonce run

  • ✅ Dynamically loaded scripts trusted

  • ❌ More complex to implement

Good for: High-security applications (banking, healthcare)

Real-World Implementation

Method 2: Meta Tag (Limited)

Limitations:

  • ❌ Cannot use frame-ancestors

  • ❌ Cannot use report-uri / report-to

  • ❌ Cannot use sandbox

  • ✅ Can use most other directives

Testing CSP: Report-Only Mode

Use this before enforcing CSP!

What happens:

  • ✅ Violations are reported but not blocked

  • ✅ You can see what would break

  • ✅ Safe to test in production

Setting Up Violation Reporting

Client-Side Violation Monitoring

Common CSP Mistakes & Fixes

Mistake 1: Using 'unsafe-inline' Everywhere

Why bad: Inline XSS can still work

Fix:

Mistake 2: Overly Permissive Wildcards

Fix:

Mistake 3: Forgetting frame-ancestors

Fix:

CSP Compatibility: Progressive Enhancement


HttpOnly Cookies

Protecting Your Session Tokens

Think of it as: A vault for your cookies that JavaScript can't open.

When you log into a website, you get a session cookie:

Without HttpOnly, an attacker can steal it via XSS:

All Security Flags Explained

Last updated