How to Secure a Website in 2026 — The Complete Guide
Complete guide to securing a website in 2026. TLS, headers, cookies, CORS, CSP, CVEs, WAF, pentesting. Code snippets for Next.js, Express, nginx.
What "secure" actually means in 2026
Securing a website is not a single action — it is a layered defence where each layer catches what the previous missed. A modern, well-secured website has six layers: transport security, HTTP headers, cookie hygiene, CORS policy, dependency management, and active monitoring.
This guide walks through all six, in the order you should implement them, with code snippets for the stacks most developers actually use in 2026: Next.js 15, Express / Node, nginx, Cloudflare Workers, and plain static sites on Vercel / Netlify.
By the end you will have a concrete checklist, know exactly what to copy-paste, and have a plan to verify the whole thing with a free ScanMyVibe scan.
Layer 1 — Transport security (TLS)
Every modern website must be served over HTTPS. This is not negotiable. Browsers now actively warn or block mixed content, form submissions over HTTP, and insecure cookies. Let's Encrypt and Cloudflare make TLS free — there is no excuse.
The right TLS configuration in 2026:
Verify with Qualys SSL Labs for deep grade, then with ScanMyVibe for the full picture.
Layer 2 — HTTP security headers
Headers are the most powerful and most underused security layer. Set these on every response:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
In Next.js 15, set these in next.config.js:
async headers() {
return [{
source: '/(.*)',
headers: [
{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
],
}]
}
In Express, use helmet:
import helmet from 'helmet'
app.use(helmet())
In nginx:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Layer 3 — Content-Security-Policy
CSP deserves its own section because it is the single most powerful header. A strict CSP stops most XSS at the browser level, even if your code is vulnerable.
Start with a permissive Report-Only policy, collect violations for a week, then tighten. The ideal 2026 CSP uses nonces with strict-dynamic:
Content-Security-Policy: default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'; upgrade-insecure-requests
Generate nonces per request in Next.js middleware:
import { NextResponse } from 'next/server'
export function middleware(request) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const csp = `script-src 'nonce-${nonce}' 'strict-dynamic';`
const response = NextResponse.next()
response.headers.set('Content-Security-Policy', csp)
response.headers.set('x-nonce', nonce)
return response
}
Don't want to write it by hand? Use our CSP header generator.
Layer 4 — Cookies
Session cookies are the #1 target of XSS, CSRF, and session hijacking. Get the flags right and most attacks fail:
In Express:
res.cookie('session', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000,
})
In Next.js with next-auth, set these in authOptions.cookies or rely on the secure defaults (next-auth v5 gets them right).
Layer 5 — CORS
CORS is where most production sites get it wrong. The rules:
1. Never use Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true. This is explicitly forbidden by browsers and is a sign of a misconfigured server.
2. Echo a specific origin from an allowlist, not the Origin header blindly. Blind echo means any site can read your API.
3. Set Vary: Origin so CDNs cache the right variant.
4. Restrict Access-Control-Allow-Methods to what you actually use.
In Express:
const allowlist = ['https://yourapp.com', 'https://www.yourapp.com']
app.use(cors({
origin: (origin, cb) => {
if (!origin || allowlist.includes(origin)) cb(null, true)
else cb(new Error('Not allowed'))
},
credentials: true,
}))
Layer 6 — Dependency and CVE management
Outdated libraries are the single most common source of real-world compromise. Every npm package, every WordPress plugin, every Python wheel is a supply chain risk. The 2026 baseline:
ScanMyVibe fingerprints outdated client-side libraries (jQuery, Bootstrap, WordPress) and flags them automatically.
Authentication and authorization
If your site has user accounts, the auth layer is where most breaches happen. The 2026 standard:
Never roll your own JWT verification. Use the library primitives.
Active monitoring and alerting
Security drifts. A new CDN rule, a framework upgrade, a misconfigured cache — any of these can regress your posture silently. The only defence is continuous monitoring.
Pentesting and human review
Automated scanners catch configuration issues. Business-logic flaws — broken auth flows, IDOR, price manipulation — require humans. Budget for one pentest per year from a reputable vendor. Costs $5k–$25k for a typical SaaS engagement and usually finds issues no scanner could.
The complete checklist
1. HTTPS everywhere with Let's Encrypt or Cloudflare.
2. TLS 1.2 minimum, 1.3 preferred.
3. HSTS with preload submitted.
4. All security headers set.
5. Strict CSP with nonces.
6. Cookies with Secure, HttpOnly, SameSite.
7. CORS from an explicit allowlist.
8. Dependabot/Renovate configured.
9. Snyk or npm audit in CI.
10. Auth library, not custom code.
11. MFA enabled.
12. Scheduled security scans.
13. Error tracking.
14. Annual pentest.
If you check all 14, you are ahead of 99% of production sites. Verify the configuration side of this checklist with a free ScanMyVibe scan — it takes 30 seconds and tells you exactly which items are still outstanding.
For tool comparisons, see our best website security scanners of 2026 guide.