Home/Blog/What Are the Common Security Header Misconfigurations and How Do I Avoid Them?
Web Security

What Are the Common Security Header Misconfigurations and How Do I Avoid Them?

Learn about the most common security header mistakes, real-world examples of misconfigurations, and practical guidance for avoiding them.

By Inventive HQ Team
What Are the Common Security Header Misconfigurations and How Do I Avoid Them?

Common Security Header Mistakes That Weaken Your Protection

Even well-intentioned organizations implement security headers incorrectly, creating false confidence in security that doesn't actually exist. Understanding common misconfiguration patterns helps you avoid the most dangerous mistakes. These errors range from trivial formatting issues to fundamental misunderstandings of what headers actually protect against.

Mistake #1: Overly Permissive Content Security Policy

The most common CSP mistake is making it so permissive that it provides no actual protection. Examples of dangerously weak CSP configurations:

Content-Security-Policy: default-src *

This allows scripts and resources from anywhere, defeating the entire purpose of CSP. It's equivalent to having no CSP at all.

Content-Security-Policy: script-src 'unsafe-inline' *

Allowing unsafe-inline makes CSP ineffective against inline script injection attacks, which are among the most common XSS vectors.

Content-Security-Policy: default-src 'self' *

While less obviously broken than the above, allowing * alongside 'self' negates any protection benefit.

How to avoid it: Start with default-src 'self' and explicitly allow only necessary resources from specific trusted origins. Never use wildcards in CSP unless absolutely necessary, and never combine them with unsafe directives. Use report-only mode to test CSP before deployment so you understand the impact.

If you need to allow inline scripts (which is generally discouraged), use nonces or hashes rather than 'unsafe-inline':

Content-Security-Policy: script-src 'self' 'nonce-abc123def456'

Mistake #2: Missing SameSite Attributes on Cookies

Cookies without proper SameSite attributes remain vulnerable to Cross-Site Request Forgery (CSRF) attacks:

Set-Cookie: sessionid=abc123

This cookie is sent with cross-site requests, allowing attackers to forge requests on behalf of users.

How to avoid it: Always specify a SameSite attribute on sensitive cookies:

Set-Cookie: sessionid=abc123; SameSite=Strict

Use SameSite=Strict for session and authentication cookies. If you need cookies to work across some cross-site contexts, use SameSite=Lax as a minimum.

Mistake #3: HSTS Configuration Errors

Several HSTS mistakes are common:

Forgetting includeSubDomains:

Strict-Transport-Security: max-age=31536000

This protects only the main domain, leaving subdomains vulnerable to MITM attacks.

Setting max-age too short:

Strict-Transport-Security: max-age=300; includeSubDomains

A 5-minute expiration means browsers frequently discard the HSTS policy, reducing protection. The standard is 1 year (31536000 seconds) or longer.

Implementing HSTS before fully committing to HTTPS:

HSTS causes browsers to reject all HTTP connections. If you implement it before ensuring all resources load over HTTPS, users will experience broken pages.

How to avoid it: Use max-age=31536000; includeSubDomains as your standard HSTS configuration. Only implement HSTS after confirming all resources (including third-party content) load over HTTPS. Consider preload list submission only after running HSTS successfully for several months.

Mistake #4: X-Frame-Options Set to ALLOW-FROM

Some developers use an outdated X-Frame-Options configuration:

X-Frame-Options: ALLOW-FROM https://example.com

The ALLOW-FROM directive is deprecated and not supported in modern browsers. Don't rely on it for security.

How to avoid it: Use only the supported values:

  • DENY - Prevent framing completely
  • SAMEORIGIN - Allow framing only by same-origin pages
  • (omit the header or don't use ALLOW-FROM)

Mistake #5: Inconsistent Header Implementation Across Environments

Different environments (development, staging, production) sometimes have different security header configurations:

# Production
Strict-Transport-Security: max-age=31536000; includeSubDomains

# Development
# (HSTS not configured)

This creates a disconnect where development doesn't match production, meaning issues aren't caught until deployment.

How to avoid it: Use identical security header configurations across all environments. If specific configurations are needed for development (like allowing unsafe-inline for development tools), use environment-specific configuration management rather than manual differences. This ensures consistent testing.

Mistake #6: Referrer-Policy Too Permissive

Setting overly permissive referrer policies leaks user data:

Referrer-Policy: unsafe-url

This sends the full URL as referrer to all destinations, potentially including sensitive information in query parameters.

How to avoid it: Use privacy-respecting policies:

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

This balances functionality (same-origin requests get full URLs) with privacy (cross-origin requests get only the origin).

Mistake #7: Neglecting to Update Headers When Third-Party Resources Change

A common pattern: implement strict CSP, then add a third-party service later without updating CSP:

# Original CSP
Content-Security-Policy: default-src 'self'

# Application adds analytics...
# (CSP is never updated)

The application breaks because the analytics script violates CSP, and you either remove CSP or use overly permissive configurations to work around it.

How to avoid it: Implement a process where adding third-party resources requires updating relevant headers. Document every CSP exception with the reason and which third-party service necessitates it. Monitor CSP violation reports to catch unexpected changes.

Mistake #8: Misunderstanding Permissions-Policy Scope

Permissions-Policy is sometimes thought to provide complete API protection:

Permissions-Policy: camera=()

This prevents the site from using camera through the camera API, but it doesn't prevent web-based screen recording or other indirect access to video capture.

How to avoid it: Understand that Permissions-Policy controls specific browser APIs, not all possible data access. Combine it with other security controls like CSP (to prevent scripts that might try to abuse APIs) and CORS headers (to prevent cross-origin API requests).

Mistake #9: Public Reporting of CSP Violations

Some developers expose CSP violation reports publicly:

Content-Security-Policy: default-src 'self'; report-uri /public/csp-violations

CSP reports can reveal application architecture and third-party services you use, providing reconnaissance information to attackers.

How to avoid it: Report CSP violations to an endpoint that requires authentication or is not publicly accessible. Monitor these reports internally rather than exposing them:

Content-Security-Policy: default-src 'self'; report-uri /admin/csp-violations

Mistake #10: Implementing Headers Without Testing Across Browsers

Headers sometimes work in some browsers but not others:

X-Content-Type-Options: nosniff

Works in modern browsers but might interact unexpectedly with older browsers in particular environments.

How to avoid it: Test security headers across target browsers. Use tools like caniuse.com to verify browser support. Test not just that headers are sent, but that they have the intended security effect in each browser you support.

Mistake #11: Not Accounting for Browser Parsing Differences

CSP and other headers with complex syntax can be parsed differently across browsers:

Content-Security-Policy: script-src 'self' https: 'unsafe-inline'

Different browsers interpret https: differently (some allow any HTTPS source, others require specific domains). The header's behavior might vary across browsers.

How to avoid it: Use explicit domain whitelists rather than protocol wildcards:

Content-Security-Policy: script-src 'self' cdn.trusted.com

Test in each target browser to ensure behavior matches your expectations.

Mistake #12: Setting Wrong Directives for Your Use Case

Some organizations implement headers that don't match their threat model:

X-Frame-Options: DENY

If you legitimately need to iframe your application for partner integration, DENY breaks functionality. SAMEORIGIN would be more appropriate.

How to avoid it: Before implementing each header, understand what threats it addresses and whether those threats apply to your application. For example, if you don't process payments, you might prioritize different headers than a payment processor would.

Mistake #13: Forgetting to Apply Headers to Error Responses

Security headers sometimes only appear on successful responses:

If 404 or 500 error pages don't include security headers, attackers gain information about your application's behavior without the same protection.

How to avoid it: Configure your web server to apply security headers to all responses, including error pages. Use the always directive in Apache or equivalents in other servers:

Header always set X-Content-Type-Options "nosniff"

Mistake #14: Not Combining Security Headers with Other Controls

Implementing security headers but neglecting other protections:

Content-Security-Policy: default-src 'self'
# (No HTTPS enforcement, no authentication, weak dependencies)

CSP alone doesn't protect against all attack vectors. It should be one layer in defense-in-depth.

How to avoid it: Implement security headers as part of a comprehensive strategy including:

  • HTTPS everywhere (enforced by HSTS)
  • Input validation and output encoding
  • Regular security updates for dependencies
  • Authentication and authorization controls
  • Security testing (SAST, DAST, penetration testing)

Mistake #15: Header Syntax Errors

Simple typos or formatting mistakes render headers ineffective:

Strict-Transport-Security max-age=31536000; includeSubDomains
# Missing colon after header name

Content-Security-Policy: defualt-src 'self'
# Typo in directive name (defualt vs default)

These malformed headers might be silently ignored by browsers, creating false confidence in security.

How to avoid it: Use automated validation tools to check header syntax. Security Header Analyzers and browser developer tools catch these issues. Use linting tools in your build process to validate headers before deployment.

Testing for Misconfigurations

Use these tools to catch misconfigurations:

Security Headers Analyzer - Scans your site and reports missing or misconfigured headers.

Mozilla Observatory - Provides detailed grades and recommendations for security headers.

Browser Developer Tools - Show what headers were actually sent and whether they're valid.

Automated Testing - Integrate header validation into your CI/CD pipeline to catch configuration changes before they reach production.

Avoiding Misconfiguration Through Process

Beyond technical controls, implement process improvements:

  1. Documentation - Document why each header is configured as it is
  2. Code Review - Review header changes just like you review code
  3. Testing - Test header functionality alongside application testing
  4. Monitoring - Monitor for CSP violations and other header-related issues
  5. Updates - Review headers periodically as new headers and directives are introduced

Conclusion: Effective Header Implementation Requires Attention to Detail

Security headers are powerful when correctly configured but can provide false confidence when misconfigured. Avoiding these common mistakes requires understanding not just what each header does, but why you're implementing it and what threats it actually protects against. Use automated tools to catch syntax errors and configuration issues, combine headers with other security controls, and maintain ongoing monitoring to ensure headers continue protecting your application as it evolves.

Need Expert IT & Security Guidance?

Our team is ready to help protect and optimize your business technology infrastructure.