Security Related HTTP Headers

Version: 1.1


Introduction

This document summarizes the Security Related HTTP Headers which should be considered by WSO2 engineers while engineering WSO2 products, as well as applications used within the organization.

Mandatory Headers

The below list consists of standard and non-standard security-related HTTP headers, that must be enabled in order to enhance the security aspects of web applications:

X-XSS-Protection: 1; mode=block: Enables reflected XSS protection in supported web browsers1.

X-Content-Type-Options: nosniff: Disable mime sniffing, which can result in reflected or stored XSS in certain browsers2.

Configurable Headers

In addition, the following security headers should be configured according to the requirement of the application and they can be customized based on URL pattern:

X-Frame-Options: DENY: Disable embedding web applications in iframes or frames3.

X-Frame-Options: SAMEORIGIN: Allow embedding web applications in iframes or frames, only within the same origin3.

Production Recommendations

Production or staging deployments (with CA signed certificates) should enable the following headers for additional security:

Strict-Transport-Security: max-age=15768000; includeSubDomains: Prevent any communication over HTTP, since the time the last response was received with the aforementioned header, up-to duration defined in max-age4.

Security headers that need to be set with an external filter (based on customer and security needs) or that should be incorporated into the Tomcat filter in future release includes the following:

Public-Key-Pins: pin-sha256="<sha256>"; pin-sha256="<sha256>"; max-age=15768000; includeSubDomains: Instructs the web client to associate a specific cryptographic public key with a certain web server to prevent MITM attacks with forged certificates5.

Content-Security-Policy: Allow declaring what dynamic resources are allowed to load to serve current response67. Replaces X-Fame-Options and X-XSS-Protection, non-standard headers with standardized headers. For additional detail refer to Content-Security-Policy.com6.

Securing Java Web Applications

Recommended web.xml filter mapping for development environments is as follows (WSO2 products should be released with this default configuration):

<filter>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <init-param>
        <param-name>hstsEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

Recommandation Production Configuration

Recommended web.xml filter mapping for production environments is as follows:

<filter>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <init-param>
        <param-name>hstsMaxAgeSeconds</param-name>
        <param-value>15768000</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

Customized Configuration

It is possible to use filter mappings to cater to product level customizations required. For example in order to enable X-Frame-Options only for particular URLs, below configuration can be used:

<filter>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <!-- Disable sending X-Frame-Options with all responses-->
    <init-param>
       <param-name>antiClickJackingEnabled</param-name>
       <param-value>false</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>HttpHeaderSecurityFilter_AntiClickJacking</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <!-- Disable other headers except X-Frame-Options (not required, but enhances performance)-->
    <init-param>
        <param-name>hstsEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>blockContentTypeSniffingEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xssProtectionEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter_AntiClickJacking</filter-name>
    <url-pattern>/carbon/*</url-pattern>
    <url-pattern>/dashboard/*</url-pattern>
</filter-mapping>

If an application requires enabling SAMEORIGIN framing only for a particular URL, below configuration can be used :

<filter>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <init-param>
        <param-name>hstsEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>
<filter>
    <filter-name>HttpHeaderSecurityFilter_AntiClickJacking_SpecialURL</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <!-- Disable other headers except X-Frame-Options (not required, but enhances performance)-->
    <init-param>
        <param-name>hstsEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>blockContentTypeSniffingEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xssProtectionEnabled</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>antiClickJackingOption</param-name>
        <param-value>SAMEORIGIN</param-value>
    </init-param>
</filter>
<!-- Global filter mapping -->
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
<!-- Overriding filter mapping for the specific URL, should come after global filter mapping-->
<filter-mapping>
    <filter-name>HttpHeaderSecurityFilter_AntiClickJacking_SpecialURL</filter-name>
    <url-pattern>/special_url/*</url-pattern>
</filter-mapping>

Further details on configuration are available at the Tomcat official documentation on HTTP_Header_Security_Filter8 and relevant source files9.

Securing Jaggery Applications

It is required to upgrade the Jaggery version to 0.12.6 or later.

Recommended jaggery.conf filter mapping for development environments is as follows (WSO2 products should be released with this default configuration):

"filters":[
    {
        "name":"HttpHeaderSecurityFilter",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter",
        "params" : [{"name" : "hstsEnabled", "value" : "false"}]
    }
],
"filterMappings":[
    {
        "name":"HttpHeaderSecurityFilter",
        "url":"*"
    }
]

Recommandation Production Configuration

Recommended jaggery.conf filter mapping for production environments is as follows :

"filters":[
    {
        "name":"HttpHeaderSecurityFilter",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter"
        "params" : [{"name" : "hstsMaxAgeSeconds", "value" : "15768000"}]
    }
],
"filterMappings":[
    {
        "name":"HttpHeaderSecurityFilter",
        "url":"*"
    }
]

Customized Configuration

It is possible to use filter mappings to cater to product-level customizations required. For example, to enable X-Frame-Options only for particular URLs, the below configuration can be used:

"filters":[
    {
        "name":"HttpHeaderSecurityFilter",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter"
        "params" : [{"name" : "antiClickJackingEnabled", "value" : "false"}]
    },
    {
        "name":"HttpHeaderSecurityFilter_AntiClickJacking",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter"
        "params" : [
            {"name" : "hstsEnabled", "value" : "false"},
            {"name" : "blockContentTypeSniffingEnabled", "value" : "false"},
            {"name" : "xssProtectionEnabled", "value" : "false"}
        ]
    }
],
"filterMappings":[
    {
        "name":"HttpHeaderSecurityFilter",
        "url":"*"
    },
    {
        "name":"HttpHeaderSecurityFilter_AntiClickJacking",
        "url":"/example1/*"
    },
    {
        "name":"HttpHeaderSecurityFilter_AntiClickJacking",
        "url":"/example2/*"
    }
],

If an application requires enabling SAMEORIGIN framing only for a particular URL, below configuration can be used:

"filters":[
    {
        "name":"HttpHeaderSecurityFilter",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter",
        "params" : [{"name" : "hstsEnabled", "value" : "false"}]
    },
    {
        "name":"HttpHeaderSecurityFilter_AntiClickJacking_SpecialURL",
        "class":"org.apache.catalina.filters.HttpHeaderSecurityFilter"
        "params" : [
            {"name" : "hstsEnabled", "value" : "false"},
            {"name" : "blockContentTypeSniffingEnabled", "value" : "false"},
            {"name" : "xssProtectionEnabled", "value" : "false"},
            {"name" : "antiClickJackingOption", "value" : "SAMEORIGIN"}
       ]
    }
],
"filterMappings":[
    {
        "name":"HttpHeaderSecurityFilter",
        "url":"*"
    },
    {
        "name":"HttpHeaderSecurityFilter_AntiClickJacking_SpecialURL",
        "url":"/special_url/*"
    }
],

Further details on configuration are available at the Tomcat official documentation on HTTP_Header_Security_Filter8 and relevant source files9.

References