Enhancing Your Website Security with Security Headers

Bartosz Matusiak
GumGum Tech Blog
Published in
7 min readJul 31, 2024

In today’s digital landscape, ensuring the security of your web applications and websites is paramount. Cyber attacks are becoming more sophisticated and prevalent, targeting vulnerabilities that can compromise user data and overall site integrity. To mitigate these risks, implementing security headers is a crucial step.

In this blog post, we will discuss what security headers are, why they are important, and how you can implement them to enhance the security of your website. We will cover key security headers such as Content-Security-Policy, Permissions-Policy, Referrer-Policy, Strict-Transport-Security, X-Frame-Options, and X-Content-Type-Options, providing examples and configurations for each.

By the end of this post, you will better understand how these security headers work and how to apply them effectively to protect your web applications from various attacks.

Content-Security-Policy (CSP)

The ‘Content-Security-Policy (CSP) Sources’ chart illustrates the distribution of content sources specified in the CSP configuration.

The Content-Security-Policy (CSP) header is designed to specify which content sources are permitted to load on your site. This additional layer of security helps detect and mitigate certain types of attacks, including XSS and data injection attacks. Here are some example configurations:

  • Allow content only from the same domain:
Content-Security-Policy: default-src 'self'

This setting ensures that all content sources must come from the same domain as the site itself.

  • Allow scripts from the same domain and a specific external source:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
  • Allow images from the same domain and any subdomains:
Content-Security-Policy: default-src 'self'; img-src 'self' *.yourdomain.com

Permissions-Policy

Geolocation permission is fully allowed (100%), while Microphone and Camera permissions are completely restricted (0%).

The Permissions-Policy header lets you control which browser features can be used on your site. This can prevent unauthorized access to sensitive features. Here are some example configurations:

  • Block access to geolocation:
Permissions-Policy: geolocation=()

This setting blocks access to the geolocation feature.

  • Allow geolocation only for the same origin:
Permissions-Policy: geolocation=(self)
  • Block access to camera and microphone:
Permissions-Policy: camera=(), microphone=()

Referrer-Policy

The ‘Referrer-Policy Settings’ chart shows the percentage of referrer information included for different policy settings. The ‘no-referrer’ policy includes 100% of referrer information, ‘same-origin’ includes 70%, and ‘origin’ includes 30%.

The Referrer-Policy header controls how much referrer information is included with requests. This can help protect user privacy and reduce information leakage. Here are some example configurations:

  • Do not send any referrer information:
Referrer-Policy: no-referrer

This setting ensures that no referrer information is sent with requests.

  • Send the referrer only when the request is to the same origin:
Referrer-Policy: same-origin
  • Send the full URL in the referrer:
Referrer-Policy: no-referrer-when-downgrade

When this policy is set, the browser sends the full URL as the referrer, but only if the request does not downgrade the security level. This means that the referrer will be included when transitioning from HTTPS to HTTPS or from HTTP to HTTP, but it will not be included when transitioning from HTTPS to HTTP.

Strict-Transport-Security (HSTS)

The ‘Strict-Transport-Security (HSTS)’ chart shows the percentage of connection usage for different protocols. The HTTPS protocol is used 100% of the time, while the HTTP protocol is not used at all (0%).

The Strict-Transport-Security (HSTS) header instructs browsers to only access the site using HTTPS, thereby enhancing the connection's security. A typical configuration might look like this:

  • Enforce HTTPS for one year:
Strict-Transport-Security: max-age=31536000
  • Enforce HTTPS for one year, including subdomains:
Strict-Transport-Security: max-age=31536000; includeSubDomains
  • Enforce HTTPS for one year, including subdomains, and preload:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

This ensures that all connections enforce HTTPS for one year, including subdomains, and submit the site to the HSTS preload list. This directive asks browsers to preload the HSTS settings, ensuring the site is always accessed over HTTPS even on the first visit.

X-Frame-Options

The ‘X-Frame-Options Settings’ chart illustrates the distribution of different X-Frame-Options settings used.

The X-Frame-Options header specifies whether the site can be embedded in a frame. This helps protect against clickjacking attacks. An example configuration:

  • Do not allow the site to be framed:
X-Frame-Options: DENY

This setting ensures that the site cannot be embedded in any frame.

  • Allow framing only from the same origin:
X-Frame-Options: SAMEORIGIN
  • Allow framing from a specific trusted source:
X-Frame-Options: ALLOW-FROM https://trusted.source.com

X-Content-Type-Options

The ‘X-Content-Type-Options Settings’ chart shows the percentage of MIME type sniffing settings. The ‘nosniff’ setting, which prevents MIME type sniffing, is used 80% of the time, while the ‘sniff’ setting, which allows MIME type sniffing, is used 20% of the time.

The X-Content-Type-Options header prevents browsers from trying to “guess” the MIME type of content and forces them to stick to the declared type. The only valid value for this header is:

  • Prevent MIME type sniffing:
X-Content-Type-Options: nosniff

This prevents MIME sniffing attacks, which could turn non-executable MIME types into executable ones.

Testing Your Site

After implementing security headers, it’s crucial to test your site for security to ensure that the headers are properly configured and effective. Here are some tools and methods you can use to perform these tests.

Using ZAP Proxy

ZAP (Zed Attack Proxy) is an open-source security tool maintained by OWASP. It helps find vulnerabilities in web applications by performing automated scans and manual testing.

How to Use ZAP Proxy:

  1. Download and Install:
  • You can download ZAP Proxy from the official website. Follow the installation instructions for your operating system.

2. Initial Setup:

  • Launch ZAP Proxy and set up the local proxy by configuring your browser to use ZAP as the proxy server. This allows ZAP to intercept and analyze the traffic between your browser and the web application.

3. Automated Scanning:

  • Use the automated scanning feature to perform a quick scan of your website. This will identify common vulnerabilities and provide a report with recommendations.

4. Manual Testing:

  • Perform manual testing by exploring your website within the ZAP interface. You can use features like the spider, fuzzer, and breakpoints to identify and analyze potential security issues.

5. Review Reports:

  • After the scan, review the generated reports to identify any security vulnerabilities. ZAP provides detailed information about each issue, including its severity and recommendations for remediation.

Using securityheaders.com

SecurityHeaders.com is a simple online tool that scans your website for security headers and provides a report on their presence and configuration.

How to Use SecurityHeaders.com:

  1. Visit the Website:

2. Enter Your URL:

  • Enter the URL of your website in the search bar and click the “Scan” button.

3. Review Results:

  • The tool will generate a report that lists your site's security headers and configurations. It also provides a grade based on the overall security of your headers.

4. Implement Recommendations:

  • Review the recommendations in the report and make necessary adjustments to your security headers to improve your website’s security score.

Regular Testing and Updates

By implementing these security headers and regularly testing your site with tools like ZAP Proxy and SecurityHeaders.com, you can significantly enhance the security of your web application. It’s essential to regularly review and update your security settings to stay protected against emerging threats.

Implementing Security Headers in Your Project

Implementing security headers in your web application is a crucial step to enhance security. Here's a guide on how to add these headers to your project using various web servers and frameworks.

Adding Headers in Nginx

For Nginx, you can add security headers in your configuration file (usually located at /etc/nginx/nginx.conf or /etc/nginx/conf.d/default.conf). Here’s an example configuration:

server {
listen 80;
server_name yourdomain.com;
location / {
add_header Content-Security-Policy "default-src 'self'";
add_header Permissions-Policy "geolocation=()";
add_header Referrer-Policy "no-referrer";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
}
# Other configurations…
}

Adding Headers in Apache

For Apache, you can add security headers in your .htaccess file or in the main configuration file (httpd.conf). Here’s an example:

<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'"
Header set Permissions-Policy "geolocation=()"
Header set Referrer-Policy "no-referrer"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set X-Frame-Options "DENY"
Header set X-Content-Type-Options "nosniff"
</IfModule>

Adding Headers in Node.js (Express)

If you are using Express in a Node.js application, you can use the helmet middleware to set security headers easily:

const express = require('express');
const helmet = require('helmet');

const app = express();

app.use(helmet());

app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
// Other directives...
},
}));

app.use(helmet.permissionsPolicy({
features: {
geolocation: ["'none'"]
// Other features...
},
}));

app.use(helmet.referrerPolicy({ policy: 'no-referrer' }));

app.use(helmet.hsts({
maxAge: 31536000,
includeSubDomains: true,
preload: true
}));

app.use(helmet.frameguard({ action: 'deny' }));

app.use(helmet.noSniff());

// Other configurations...

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Adding Headers in ASP.NET

For ASP.NET, you can add security headers in the web.config file:

<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="default-src 'self'" />
<add name="Permissions-Policy" value="geolocation=()" />
<add name="Referrer-Policy" value="no-referrer" />
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains; preload" />
<add name="X-Frame-Options" value="DENY" />
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

Summary

Implementing these headers can significantly boost the security of your web applications by mitigating various attacks. Regularly review and update your security settings to stay protected against emerging threats.

We’re always looking for new talent! View jobs.

Follow us: Facebook | Twitter | LinkedIn | Instagram

--

--