Missing HTTP security headers can leave websites and applications exposed to a variety of attacks. If the browser fails to enforce security measures due to missing security headers, apps can be far more vulnerable to attacks like cross-site scripting and clickjacking, increasing the risk of unauthorized access, sensitive data exposure, and further exploitation by malicious actors.
HTTP security headers are a crucial part of web security, providing an additional layer of protection against common threats such as cross-site scripting (XSS), clickjacking, and content injection attacks. The term covers several different HTTP headers that instruct the browser how to behave safely when connecting to servers and handling site content. Using and correctly configuring the right headers can greatly enhance overall security by heading off entire classes of vulnerabilities.
Security headers play a key role in defending web applications from attacks that exploit browser behavior. They can apply a variety of directives to ensure safe browsing across web pages, restrict access to subdomains, and manage referer policies to minimize data leakage. Among other things, headers can help modern browsers enforce HTTP Strict Transport Security (HSTS), control cross-origin requests (CORS), mitigate cross-site scripting attacks, and eliminate MIME type sniffing vulnerabilities. When properly defined and maintained, security headers are a vital part of implementing security policies to prevent unauthorized content from loading or restrict the execution of unexpected (and potentially malicious) scripts.
When an HTTP security header is missing, an application may be more vulnerable to specific attack vectors. Here are some common risks associated with missing (or misconfigured) security headers:
The examples below use a typical subset of possible HTTP security headers, but the specific headers you need will depend on your specific use case. Different applications have different security and policy requirements, and the appropriate headers will vary based on the technologies and frameworks in use. If you’re seeing a warning about missing security headers, it will usually also tell you which header is missing or misconfigured.
As a general rule, HSTS and CSP are the two minimum must-have headers—one to enforce encryption and the other to cover the majority of content-related security requirements. For a detailed discussion of security headers, see our white paper on security headers and an in-depth blog post on why HTTP headers are an easy way to harden your applications.
While HTTP headers can also be set at the application level, setting them on the server is the usual practice. Adding HTTP security headers depends on your web server and technology stack. Below are sample configuration file entries for common web servers, demonstrating some typical security header choices and values:
Edit the .htaccess
or main configuration file:
Header set X-Frame-Options "SAMEORIGIN"Header set X-Content-Type-Options "nosniff"Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'"Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Modify the server block in the nginx.conf
file to improve security:
add_header X-Frame-Options "DENY";add_header X-Content-Type-Options "nosniff";add_header Content-Security-Policy "default-src 'self'";add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
Edit the web.config file. Note that IIS may require a restart after modifying this file to apply changes, especially for older server versions.
<configuration> <system.webServer> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="DENY" /> <add name="X-Content-Type-Options" value="nosniff" /> <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" /> <add name="Content-Security-Policy" value="default-src 'self'" /> </customHeaders> </httpProtocol> </system.webServer></configuration>
As an example of adding security headers in the application, you can use the Helmet middleware to automatically set a range of security headers from your Express.js app. While Helmet applies default security settings, customization may be required for specific use cases to ensure compatibility with APIs, especially setting up CORS to handle cross-origin requests correctly and securely.
const helmet = require('helmet');app.use(helmet());
You can verify whether your security headers are properly configured using the following methods:
curl -I https://example.com
to display the response headers.Implementing HTTP security headers can be an easy way to enhance web security, often requiring minimal or no modifications to the application itself. However, keeping up with evolving browser vendor support can be challenging, particularly when managing security configurations across numerous websites. Because security standards change frequently, ensuring your headers remain effective requires regular updates and monitoring.
To help maintain strong security, Invicti includes vulnerability checks that assess the presence and correctness of recommended HTTP security headers. These automated checks detect missing or improperly configured headers and provide clear guidance on how to optimize them. This ensures your web applications remain protected against emerging threats and you can quickly catch any gaps caused by new or modified deployments.