Back to Blog
Security HeadersWeb SecurityHTTP

How to Fix Missing Security Headers

Waqaya Security TeamMarch 20, 20268 min read

Why Security Headers Matter

HTTP security headers are your website's first line of defense against common web attacks like cross-site scripting (XSS), clickjacking, and MIME-type sniffing. Despite being one of the simplest security measures to implement, a staggering number of websites lack them entirely.

In this guide, we'll walk through the most critical security headers, explain what each one does, and show you exactly how to implement them on nginx, Apache, and Express.js servers.

The Essential Security Headers

1. Content-Security-Policy (CSP)

CSP is the most powerful security header available. It tells the browser exactly which resources are allowed to load on your page, effectively preventing XSS attacks by blocking unauthorized scripts.

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'

Start restrictive and loosen as needed. Begin with default-src 'self' and add exceptions only for resources you actually use.

2. Strict-Transport-Security (HSTS)

HSTS forces browsers to only connect to your site over HTTPS, preventing SSL stripping attacks and accidental HTTP connections.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

The max-age value is in seconds — 31536000 equals one year. The preload directive allows your domain to be included in browser preload lists.

3. X-Frame-Options

This header prevents your site from being embedded in iframes on other domains, protecting against clickjacking attacks.

X-Frame-Options: DENY

Use DENY to block all framing, or SAMEORIGIN if you need to iframe your own pages.

4. X-Content-Type-Options

Prevents browsers from MIME-type sniffing, which can turn non-executable content into executable content.

X-Content-Type-Options: nosniff

This is a simple, zero-risk header — always include it.

5. Referrer-Policy

Controls how much referrer information is sent when users navigate away from your site.

Referrer-Policy: strict-origin-when-cross-origin

This sends the full URL for same-origin requests but only the origin for cross-origin requests — a good balance of functionality and privacy.

6. Permissions-Policy

Formerly Feature-Policy, this header controls which browser features your site can use — camera, microphone, geolocation, etc.

Permissions-Policy: camera=(), microphone=(), geolocation=()

Disable features you don't use. This reduces your attack surface and signals to browsers that these APIs should be blocked.

Implementation Guide

nginx

server {
    add_header Content-Security-Policy "default-src 'self'" always;
    add_header Strict-Transport-Security "max-age=31536000; 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;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}

Apache (.htaccess)

Header always set Content-Security-Policy "default-src 'self'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"

Express.js (Node.js)

const helmet = require('helmet');
app.use(helmet());

// Or manually:
app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy', "default-src 'self'");
    res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
    res.setHeader('X-Frame-Options', 'DENY');
    res.setHeader('X-Content-Type-Options', 'nosniff');
    res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
    res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
    next();
});

Test Your Headers

After implementing these headers, use Waqaya's Security Headers Analyzer to verify they're correctly configured. The tool checks for all 6 headers above plus additional best practices and gives you an instant grade.

Remember: security headers are not a one-time setup. Review them regularly as your application evolves and new headers become available.

Need expert security help?

Our team provides enterprise-grade security audits, cloud consulting, and vulnerability assessments. Let us protect your business.

Book a Free Consultation