Cryptography & Security

Web Security

How browsers enforce isolation, how attackers break it, and the headers, tokens, and policies that keep web applications safe.

01 / Foundations

Same-Origin Policy & CORS

Same-Origin Policy (SOP)

The browser's most fundamental security boundary. Two URLs share an origin only when all three parts match: protocol, host, and port.

URLCompared to https://app.io:443/pageSame Origin?
https://app.io:443/otherSame protocol, host, portYes
http://app.io:443/pageDifferent protocolNo
https://api.app.io:443/pageDifferent host (subdomain)No
https://app.io:8080/pageDifferent portNo

SOP blocks cross-origin reads by default: scripts on origin A cannot read responses from origin B. Writes (form submissions, navigations) and embeds (images, scripts, iframes) are generally allowed.

Key Insight
SOP protects reading data, not sending requests. A cross-origin POST still fires; the browser just hides the response. This is why CSRF attacks are possible even with SOP in place.

Cross-Origin Resource Sharing (CORS)

CORS is the opt-in mechanism that lets a server relax SOP for specific origins. The server declares who may read its responses via Access-Control-* headers.

CORS Preflight Flow
Browser
OPTIONS /api
Server
Server
Access-Control-Allow-*
Browser
Browser
Actual GET/POST
Server

Simple requests (GET/POST with standard headers and content types like text/plain) skip preflight. Preflighted requests (custom headers, methods like PUT/DELETE, or JSON content type) trigger an OPTIONS preflight first.

# Key CORS response headers
Access-Control-Allow-Origin: https://app.io
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400
Warning
Setting Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true is rejected by browsers. If you need credentials, you must specify the exact origin.
02 / Injection Attacks

Cross-Site Scripting (XSS)

XSS lets an attacker inject malicious scripts into pages viewed by other users. The browser executes the script in the context of the victim's session, giving access to cookies, DOM, and APIs.

Reflected XSS

Malicious input is echoed back in the server response. Requires the victim to click a crafted link. Example: search query reflected in results page without escaping.

Stored XSS

Payload is persisted (database, comment, profile field) and served to every user who views the page. More dangerous because no user interaction beyond visiting the page is needed.

DOM-Based XSS

The vulnerability is entirely in client-side JavaScript. The page reads from a source (e.g., location.hash) and writes to a sink (e.g., innerHTML) without sanitization.

Prevention

DefenseWhat It DoesLimitation
Output escapingEncode < > & " ' before inserting into HTMLMust be context-aware (HTML vs. JS vs. URL)
Input sanitizationStrip or neutralize dangerous tags/attributes (e.g., DOMPurify)Allow-lists are fragile; keep libraries updated
Content Security PolicyBrowser-enforced allow-list of script sourcesComplex to deploy; unsafe-inline weakens it
HttpOnly cookiesPrevents document.cookie access from JSDoesn't prevent XSS itself, only limits cookie theft
// BAD: DOM-based XSS
document.getElementById('output').innerHTML = location.hash.slice(1);

// GOOD: use textContent instead
document.getElementById('output').textContent = location.hash.slice(1);
03 / Forged Requests

Cross-Site Request Forgery (CSRF)

CSRF tricks a logged-in user's browser into making an unwanted request to a site where they're authenticated. The browser automatically attaches cookies, so the server sees a legitimate session.

CSRF Attack Flow
User visits evil.com
->
evil.com serves hidden form
Browser auto-submits form to bank.com
->
bank.com sees valid session cookie
bank.com processes transfer

Prevention

DefenseHow It Works
CSRF tokensServer embeds a random token in forms; verifies it on submission. The attacker's page cannot read the token due to SOP.
SameSite cookiesSameSite=Strict blocks the cookie on all cross-site requests. SameSite=Lax allows top-level GET navigations but blocks cross-site POST.
Double-submit cookieToken sent as both a cookie and a request parameter. Server checks they match. No server-side state needed.
Custom request headersRequire a custom header (e.g., X-Requested-With) that triggers CORS preflight, which the attacker's form cannot set.
Modern Default
Most browsers now default to SameSite=Lax, which blocks cross-site POST requests from automatically attaching cookies. This significantly reduces CSRF risk without any server-side changes.
04 / Security Headers

Content Security Policy & Cookies

Content Security Policy (CSP)

CSP is a response header that tells the browser which sources of content are allowed. It is the strongest defense against XSS because it prevents inline scripts and restricts where scripts can load from.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-abc123' https://cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src *;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';
DirectiveControlsExample
default-srcFallback for all resource types'self'
script-srcJavaScript sources'nonce-xyz' https://cdn.io
style-srcCSS sources'self' 'sha256-...'
img-srcImage sources* data:
connect-srcFetch, XHR, WebSocket targets'self' https://api.io
frame-ancestorsWho can embed this page in an iframe'none' (prevents clickjacking)

Nonces: Generate a random nonce per request and include it in both the CSP header and each <script nonce="..."> tag. Only scripts with the matching nonce execute. Hashes: Alternatively, specify the SHA-256 hash of the inline script content in the CSP header.

Warning
'unsafe-inline' and 'unsafe-eval' defeat the purpose of CSP. If you must use inline scripts, use nonces or hashes instead.

Cookie Security Attributes

AttributePurposeRecommended Value
SecureCookie only sent over HTTPSAlways set for session cookies
HttpOnlyBlocks JavaScript access via document.cookieAlways set for session cookies
SameSiteControls cross-site cookie sendingLax (default) or Strict
DomainWhich domains receive the cookieOmit to restrict to exact origin
PathURL path prefix required for sending/ unless scoping is needed
Set-Cookie: session=abc123;
  Secure;
  HttpOnly;
  SameSite=Lax;
  Path=/;
  Max-Age=3600
05 / Other Attacks

Clickjacking, SSRF & More

Clickjacking

Attacker overlays an invisible iframe of the target site over a decoy page. User thinks they're clicking the decoy but actually interacts with the hidden site. Defend with frame-ancestors 'none' in CSP or X-Frame-Options: DENY.

SSRF

Server-Side Request Forgery: attacker tricks the server into making requests to internal services (e.g., cloud metadata endpoints at 169.254.169.254). Defend with allow-lists for outbound URLs and blocking private IP ranges.

Open Redirects

Application redirects to a user-supplied URL without validation. Attacker uses it for phishing: app.com/redirect?url=evil.com. Defend with allow-lists of permitted redirect domains.

SQL Injection

Attacker injects SQL through user input that is concatenated into queries. Defend with parameterized queries / prepared statements, never string concatenation.

Command Injection

User input passed to shell commands (e.g., os.system("ping " + ip)). Defend by avoiding shell calls; use language-native libraries or strict input validation.

Path Traversal

Attacker uses ../ sequences to access files outside the intended directory. Defend by canonicalizing paths and validating they stay within the allowed root.

06 / Framework

OWASP Top 10 Overview

The OWASP Top 10 is a widely-adopted awareness document for web application security. The 2021 edition reorganized categories based on data and community input.

#CategoryKey Concern
A01Broken Access ControlUsers acting beyond their permissions; IDOR, missing function-level access control
A02Cryptographic FailuresSensitive data exposure; weak encryption, plaintext storage, missing TLS
A03InjectionSQL, NoSQL, OS, LDAP injection via untrusted input in queries/commands
A04Insecure DesignFlawed architecture; missing threat modeling, no security by design
A05Security MisconfigurationDefault credentials, open cloud storage, verbose error messages, missing headers
A06Vulnerable ComponentsOutdated libraries, frameworks with known CVEs
A07Auth & Identification FailuresBroken authentication, session fixation, weak passwords
A08Software & Data Integrity FailuresUntrusted CI/CD pipelines, insecure deserialization, unsigned updates
A09Security Logging & Monitoring FailuresNo audit trail, alerts, or incident detection
A10Server-Side Request ForgerySSRF via unvalidated URLs fetched by the server
Key Insight
Broken Access Control moved to #1 in 2021, overtaking Injection. This reflects a shift: frameworks now prevent injection by default (parameterized queries, auto-escaping templates), but access control remains a manual, business-logic problem that developers must implement correctly.

Test Yourself

Score: 0 / 10
Question 01
Which three components define a web origin under the Same-Origin Policy?
An origin is defined by the tuple (protocol, host, port). The path is not part of the origin comparison.
Question 02
When does a browser send a CORS preflight (OPTIONS) request?
Simple requests (GET/POST with standard headers and content types like text/plain) skip preflight. Any custom header, non-simple method (PUT, DELETE), or content type like application/json triggers a preflight OPTIONS request.
Question 03
Which type of XSS involves a payload that is persisted in the server's database?
Stored (persistent) XSS saves the malicious payload in the database. Every user who views the affected page gets the script executed in their browser, making it the most dangerous variant.
Question 04
What does the HttpOnly cookie attribute prevent?
HttpOnly makes the cookie invisible to client-side JavaScript. It doesn't prevent XSS itself, but it stops an XSS payload from stealing session cookies via document.cookie. The Secure flag (not HttpOnly) restricts cookies to HTTPS.
Question 05
Why does CSRF work even though the Same-Origin Policy is in place?
SOP prevents reading cross-origin responses, but the request itself (including cookies) is still sent to the server. CSRF exploits this: the attacker doesn't need to read the response, just trigger a state-changing request with the victim's session cookie.
Question 06
Which SameSite cookie value blocks the cookie on all cross-site requests, including top-level navigations?
Strict blocks the cookie on all cross-site requests, even top-level GET navigations (e.g., clicking a link from another site). Lax allows top-level navigations but blocks cross-site sub-requests (forms, AJAX). None sends cookies everywhere but requires the Secure flag.
Question 07
What is the purpose of a CSP nonce?
A nonce is a random value generated per request. The server includes it in the CSP header and on each allowed <script> tag. Only scripts with a matching nonce execute, preventing injected scripts from running.
Question 08
Which CSP directive prevents a page from being embedded in an iframe (clickjacking defense)?
frame-ancestors controls which origins can embed the page in an iframe, object, or embed. Setting it to 'none' prevents all framing, which is the modern replacement for X-Frame-Options: DENY.
Question 09
In the OWASP Top 10 (2021), what is the #1 risk category?
Broken Access Control rose to #1 in 2021, replacing Injection which dropped to #3. Modern frameworks handle injection well by default, but access control remains a manual, business-logic concern.
Question 10
An attacker tricks a server into fetching http://169.254.169.254/latest/meta-data/. What type of attack is this?
SSRF occurs when an attacker makes the server issue requests to internal resources. The IP 169.254.169.254 is the cloud metadata endpoint (AWS, GCP, Azure), which can expose credentials and configuration if accessed.