Implement security headers on Azure Application Gateway

Intro

If you are a web developer or a website owner, you probably know how important it is to protect your web application from malicious attacks and unauthorized access.

One of the best ways to do that is to implement security headers in your web server configuration. These HTTP response headers instruct the browser how to behave when interacting with your website. They can help you prevent common web vulnerabilities such as cross-site scripting (XSS), clickjacking, content injection, and more.

In this blog post, I explain the function of different security headers and how you can easily add them to your website which is configured behind an Azure Application Gateway.

Security headers

As mentioned in the intro, security headers can help you prevent common attacks, such as cross-site scripting (XSS), clickjacking, and content sniffing. They can also help you optimize the loading speed and caching of your web pages. Let's take a look at some security response headers and their function.

  • Content-Security-Policy: Content Security Policy is an effective measure to protect your site from XSS attacks. By whitelisting sources of approved content, you can prevent the browser from loading malicious assets.
  • X-Frame-Options: X-Frame-Options tells the browser whether you want to allow your site to be framed or not. By preventing a browser from framing your site you can defend against attacks like clickjacking.
  • X-Content-Type-Options: X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type.
  • Referrer-Policy: Referrer Policy is a new header that allows a site to control how much information the browser includes with navigations away from a document and should be set by all sites.
  • Permissions-Policy: Permissions Policy is a new header that allows a site to control which features and APIs can be used in the browser.
  • strict-transport-security: HTTP Strict Transport Security is an excellent feature to support your site and strengthens your implementation of TLS by getting the User Agent to enforce the use of HTTPS.
  • server: The Server header is the most common header you will likely see on a site. Typically you will see values like "Microsoft-IIS/8.0" or "nginx 1.7.2". Revealing the specific software version of the server might allow the server machine to become more vulnerable to attacks against software that is known to contain security holes.

These are just some of the most important security response headers that you should configure for your web applications. By using these headers, you can improve the security of your websites.

Configuring headers on your Azure Application Gateway

Let the fun part begin and see how we can configure the above security headers on an Azure Application Gateway.

Quick note, make sure you have an Application Gateway configured with a listener that points to a website.

One of the features of Azure Application Gateway is that you can easily manipulate the headers of your incoming and outgoing requests. This gives you more control and flexibility over how your application communicates with the clients and the backend servers. To do this, you just need to go to the Rewrites section of your Application Gateway's blade and click on + Rewrite set.

Rewrite set

After this, you can set an HTTP rewrite rule on the Application Gateway scope by adding a name and clicking next. You can also create an HTTP rewrite rule per routing rule/paths you have configured.

Select scope

After the scope has been chosen, you can start creating rules in your rewrite set. You can name your rules and give them a sequence. The rule sequence helps determine the order in which the rewrite rules get executed. This is helpful when there are multiple rewrite rules in a rewrite set. The rewrite rule with a lesser rule sequence value gets executed first.

After this, you can click on Add action to create a new response header. This will show a new action entry in the pane.

Action pane

When you click on this action entry, you get a list of properties that you can use for the new header you want to configure.

  • In Rewrite type you'll have to choose Response Header.
  • In Action type you'll have to choose Set.
  • You can select a Header name from a common list. This is a predefined list created by Microsoft. If the header that you want to configure is not in this list, you should select Custom header
  • Lastly, you can set the Common header and its Header value.

Below you can find an example of the configuration for the Content-Security-Policy header. This is a common header according to Microsoft.

Content-Security-Policy

Below you can find an example of the configuration for the X-Content-Type-Options header. This is a custom header according to Microsoft.

X-Content-Type-Options

Which response headers should you configure?

The headers mentioned in the begining of this blogpost form a good default header configuration. Below you can find an example of a default configuration.

name="Content-Security-Policy" value="upgrade-insecure-requests; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; object-src 'none';"
/* This policy determines what can run on the page. It can be very strict, so make sure you understand it before you change it. I have provided a basic setting that allows most things, but it does not protect you from XSS attacks. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy */

name="X-Frame-Options" value="SAMEORIGIN"
/* Disables iframing the website from other than the origin. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options */

name="X-Content-Type-Options" value="nosniff"
/* Prevents browsers from trying to mime-sniff the content-type of a response away from the one being declared by the server. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options */ 

name="Referrer-Policy" value="strict-origin-when-cross-origin"
/* Sets the referrer policy which is the default since November 2020. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy */

name="Permissions-Policy" value="accelerometer=(self), camera=(self), geolocation=(self), gyroscope=(self), magnetometer=(self), microphone=(self), payment=(self), usb=(self)" 
/* Used to disable certain features like camera and microphone.  */
/* More information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy */

name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains; preload"
/* HSTS allows you to tell a browser that you always want a user to connect using HTTPS instead of HTTP. his policy will enforce TLS on your site and all subdomains for a year. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security */

name="Server" value=""
/* Rewrites the Server header to give less information about the origin server. You can also give this value "Azure" to inform it is running on Microsoft Azure instead of nothing. */
/* More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server */

If you would like to perform a check on your web application, you can use a site scanner like securityheaders.com. It is a free and easy-to-use tool that shows you ways to improve your header configuration.

Below you can find a report summary for my website. Please do as I say and not as I do 🙂.

Report

Conclusion

In this blog post, I have shown you how to configure security response headers on an Azure Application Gateway. This is a very easy and effective way to improve the security of your web applications. By creating a default rewrite set on the Application Gateway scope, you can apply the same security headers to all your web applications. However, you can also configure custom rules for specific applications by selecting the correct listener scope.

I hope you enjoyed this blog post and learned something new. Creating rewrite rules for security headers is a best practice that you should implement in your Azure Application Gateway today!