Security headers are your first line of defense. At Google, every response includes these headers.
Content-Security-Policy (CSP)
The most powerful security header. Controls what resources can load on your page.
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-abc123';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
font-src 'self' https://fonts.gstatic.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';Essential Headers
| Header | Value | Purpose |
|---|---|---|
| Strict-Transport-Security | max-age=31536000; includeSubDomains | Force HTTPS for 1 year |
| X-Content-Type-Options | nosniff | Prevent MIME type sniffing |
| X-Frame-Options | DENY | Prevent clickjacking |
| Referrer-Policy | strict-origin-when-cross-origin | Control referrer info |
| Permissions-Policy | camera=(), microphone=(), geolocation=() | Disable unused APIs |
| Cross-Origin-Opener-Policy | same-origin | Isolate browsing context |
| Cross-Origin-Embedder-Policy | require-corp | Prevent loading cross-origin without CORS |
Implementation
// Express middleware
app.use((req, res, next) => {
res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
res.setHeader("X-Content-Type-Options", "nosniff");
res.setHeader("X-Frame-Options", "DENY");
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
res.setHeader("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
next();
});
// Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;Testing Your Headers
- Use securityheaders.com for a quick grade
- Chrome DevTools → Network → Response Headers
- Use Report-URI or report-to for CSP violation monitoring