DevOpsil
Security
86%
Fresh

Security Headers & Configs: Cheat Sheet

Amara OkaforAmara Okafor2 min read

Essential Security Headers

HeaderValuePurpose
Strict-Transport-Securitymax-age=63072000; includeSubDomains; preloadForce HTTPS
Content-Security-Policy(see below)Control content sources
X-Content-Type-OptionsnosniffPrevent MIME sniffing
X-Frame-OptionsDENYBlock clickjacking
Referrer-Policystrict-origin-when-cross-originLimit referrer leakage
Permissions-Policycamera=(), microphone=(), geolocation=()Disable browser APIs

Nginx

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';" always;
server_tokens off;

Kubernetes Ingress (Nginx Controller)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-Frame-Options "DENY" always;
      add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"

Helmet.js (Node/Express)

const helmet = require("helmet");
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"], scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:"], frameAncestors: ["'none'"],
    },
  },
  hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },
  frameguard: { action: "deny" },
  referrerPolicy: { policy: "strict-origin-when-cross-origin" },
}));

CSP Examples

# Strict self-only
default-src 'self';

# Allow Google Fonts + Analytics
default-src 'self'; font-src 'self' fonts.gstatic.com; style-src 'self' fonts.googleapis.com; script-src 'self' www.googletagmanager.com;

# Report-only mode (monitor without blocking)
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report;

CORS (Nginx)

add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Max-Age 86400 always;

TLS Config (Nginx)

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

Validate

curl -I https://example.com           # Check response headers
curl -vI https://example.com 2>&1 | grep -E "SSL|TLS|subject|expire"
# Online: securityheaders.com  |  ssllabs.com/ssltest
Share:
Amara Okafor
Amara Okafor

DevSecOps Lead

Security-first mindset in everything I ship. From zero-trust architectures to supply chain security, I make sure your pipeline doesn't become your weakest link.

Related Articles