Web Security Fundamentals 2026: The Complete Problem-Solving Guide
By Huzi
File #551 · 4 min read
Most compromised sites are not undone by exotic zero-days — they run decent code over TLS 1.1, ship no Content-Security-Policy, and set a session cookie without HttpOnly.
The quick answer: Security in 2026 is less about genius and more about layers — transport, headers, cookies, code — each layer assuming the one above it will eventually fail. The minimum stack: twenty minutes of headers in next.config.ts, a nonce-based CSP, TLS 1.3 with post-quantum key exchange, and the quiet COOP/COEP/CORP trio.
The headers block that pays for itself
Twenty minutes in next.config.ts buys most of this; the browser enforces it for free:
// next.config.ts
const securityHeaders = [
{ key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
{ key: "Content-Security-Policy", value: "default-src 'self'; script-src 'self' 'nonce-r4nd0m'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
];
export default {
async headers() {
return [{ source: "/(.*)", headers: securityHeaders }];
},
};
What you just bought, header by header:
| Header | What it buys |
|---|---|
| Strict-Transport-Security | The browser refuses plain HTTP for two years after first seeing it |
| Content-Security-Policy | Nothing without the nonce executes; frame-ancestors stops your login page being iframed under an attacker's overlay |
| X-Content-Type-Options | The browser stops guessing file types from their bytes |
| Referrer-Policy | Your URLs stay out of other sites' referrer logs |
| Permissions-Policy | Camera and geolocation you never asked for stay off |
Preload that HSTS value only once every subdomain is on HTTPS — it kills SSL-stripping at the café-Wi-Fi level. Set it once and bas — it keeps working while you sleep.
Pro tip: Ship HSTS with preload only after every subdomain serves HTTPS — once the browser records it, plain HTTP stays refused for two years, and a straggler subdomain has no route back.
CSP: the one header doing real work
A Content-Security-Policy tells the browser exactly which scripts may run; nothing else executes. The modern way is a per-response nonce: the server generates a random value, prints it into the script tags it renders, and anything without that ticket stays inert.
No unsafe-inline, no wildcard CDNs. That one header defangs most cross-site scripting payloads — the full anatomy of that attack has its own post on this blog, as does SQL injection.
For the last gap, DOM sinks like innerHTML, add require-trusted-types-for 'script' so raw strings get refused by the browser itself.
TLS in 2026: 1.3 only, and already post-quantum
Turn off TLS 1.0, 1.1 and 1.2 on the server and keep the AEAD suites; with certificates free through Let's Encrypt's ACME rotation, an expired padlock is pure negligence now.
The genuinely new part: Chrome and Firefox negotiate X25519MLKEM768 — classical X25519 exchange hybridized with ML-KEM, the lattice scheme standardized from the Kyber work. Traffic recorded today cannot be decrypted later by a quantum machine, quietly closing the harvest-now-decrypt-later hole.
On Node 23 and above, opting in is one option:
import tls from "node:tls";
const server = tls.createServer(
{ minVersion: "TLSv1.3", groups: "X25519MLKEM768:X25519" },
handle,
);
Expiry is expiry: an expired certificate and an expired passport fail the same way — silently, and at the worst hour. HTG Travels checks document dates before booking, the way ACME rotation keeps padlocks current.
COOP, COEP, CORP — the quiet trio
Three smaller headers nobody writes about:
Cross-Origin-Opener-Policy: same-originstops another origin keeping a window handle to your tab.Cross-Origin-Embedder-Policy: require-corpmeans your page only embeds resources that explicitly opted in.Cross-Origin-Resource-Policy: same-originreturns the favour — your images and scripts cannot be pulled into another origin.
You need the full trio for SharedArrayBuffer or high-resolution timers; otherwise COOP alone is still worth sending. Each line makes the Spectre class of side-channel meaningfully harder.
Every layer in this stack exists to protect someone who never asked to be attacked.
Gaza's families live through the failure of every protection the world once promised them — keep them in your duas tonight.
We run our travel files in layers at HTG Travels. Visa paperwork checked twice before it leaves the desk, hotel names and walking distances in writing, a backup route ready for the day an airline cancels on the whole group. Umrah season, Hunza and Skardu itineraries, Schengen files — message +92 317 5054959 and feel the deadbolts.




