I want a "Red Teaming"
Michael Schneider
A Short History of HTTP Response Headers
A Response Header can be set by the web application itself, or by the configuration of the web server. The configuration is not always done by the developers, so that a coordination between the configuration and the development of the application is necessary. In the article HSTS Preload as attack vector by Marc Ruef was dealt with the fact that the header Strict-Transport-Security
can have comprehensive influence on further services than only controlling the HTTPS security policy of the web application. The Response Header can not only provide security, but also have an influence on the operation in case of a faulty configuration, described by Stefan Friedli in the article about HTTP Strict Transport Security.
We have already written some articles about security relevant Response Headers. Veit Hailperin introduced various headers in January 2016 with the article Inglorious Headers, Michael Schneider explained the usage of the Content Security Policy in August 2016, Andrea Hauser described security measures in the article Response Header Hardening in March 2018, and Michael Schneider introduced new headers in the article the Continuation of the HTTP header saga in August 2018. More than two years have passed since then, so we look at the current state of development and present new changes and emerging plans for the future of response headers.
The Expect-CT header indicates that the website supports the Certificate Transparency (CT) standard. The browser is prompted to check each certificate on the website in the public CT logs. The header is supported by Edge 79 and Chrome 61, the status in Firefox is not documented.
This header will become obsolete in June 2021, as new certificates issued in May 2018 should have support for Signed Certificate Timestamps (SCT). Certificates issued before March 2018 have a maximum validity period of 39 months, which accordingly expires in June 2021.
The header X-Frame-Options declares whether a web page may be rendered in a frame or object. The header is replaced by the directive frame-ancestors
of the Content-Security-Policy. However, since the header Content-Security-Policy
is partially supported by Microsoft Internet Explorer, the header X-Frame-Options
must be set as long as Internet Explorer is still used. Therefore, in the meanwhile this header must be set parallel to the Content-Security-Policy.
The header Content-Security-Policy is widely used and supported by all modern browsers. With Web Application Penetration Tests we usually observe a “two-step” development. First, the CSP header is set with an open directive. In most cases the directive script-src
still allows unsafe-inline
and unsafe-eval
. Only in the next stage is the website ready to use a restrictive directive.
In the future, the directive report-uri
will be replaced by report-to
. Currently report-to
is only supported in Chrome and Edge. It is planned that as soon as report-to
is implemented in most browsers, the directive report-uri
will be ignored by the browser. In order to use report-to
, a so-called endpoint must be defined, this is done via the Reporting API.
The Reporting API, specified in the W3C Working Draft dated September 25, 2018, defines the Reports-To
header, which defines one or more endpoints. The defined endpoints are then referenced by the CSP directive report-to
. An endpoint is defined in JSON format and looks like this:
Report-To: {"group":"default","max_age":10886400,"endpoints":[{"url":"https://example.com/reports","priority":1},{"url":"https://backup.example.com/reports","priority":2}]}
The JSON format is difficult to read by eye in this form, in a beautified format the content looks like this:
Report-To: { "group": "csp", "max_age": 10886400, "endpoints": [ { "url": "https://example.com/reports", "priority": 1 }, { "url": "https://backup.example.com/reports", "priority": 2 } ] }
The max_age
statement causes the browser to save the endpoint configuration for the specified time and use the list of endpoints to send reports to these URLs.
However, in the Editor’s Draft on the Reporting API of October 19, 2020, the Report-To
header has already been replaced with the Reporting-Endpoints
header. This header uses the Structured Header Format (SH) and was simplified in the configuration. For each endpoint only a name and a URL has to be defined. The header is set like this:
Reporting-Endpoints: csp="https://example.com/reports"
Since the header Report-To
has already been implemented in Chrome, both headers are still valid. In the future only the header Reporting-Endpoints
shall be used.
The web platform mechanism Origin-Policy aims to use an origin-wide configuration instead of communicating in multiple headers per HTTP response. The Draft Community Group Report from June 8, 2020 contains several changes compared to the status two years ago in the article Continuation of the HTTP Header Saga. Among other things, the header Sec-Origin-Policy
is no longer used, but only Origin-Policy
. The value of this header specifies which policy is valid for the origin:
Origin-Policy: allowed=("example-1")
The policy is provided via the URL https://example.com/.well-known/origin-policy
as JSON file:
{ "ids": ["example-1"], "content_security": { "policies": ["default-src 'none'; connect-src 'self'; img-src 'self'; style-src 'self'; frame-ancestors 'none';"] } }
The Origin-Policy is only a suggestion, which is not yet supported in any browser.
The header Feature-Policy is fully supported starting with Chrome 74 and Edge 79; partial support is available in Firefox starting with version 74. Approximately two years after the header was introduced, it has already been replaced by Permissions-Policy
. The security researcher Scott Helme had dealt with the replacement in the article Goodbye Feature Policy and hello Permissions Policy!.
The directive of the header has similarities to the header Content-Security-Policy
and looks like this:
Feature-Policy: camera 'none'; microphone 'none'; geolocation 'none'; speaker 'self'
The successor of the header Feature-Policy
is called Permissions-Policy
and is currently only experimentally supported from Chrome 86 onward. The header is specified in the Editor’s Draft dated 29 September 2020.
The format of the directive is different from the Feature-Policy
header, so it is not sufficient to rename the header if you change it. In the format of the new header, the previous example looks like this:
Permissions-Policy: camera=(), microphone=(), geolocation=(), speaker=(self)
Until the header Permissions-Policy
is implemented in the most common browsers, a parallel operation of the two headers is necessary.
The development of Response Headers has been driven forward at a rapid pace over the last two years. Header support is already implemented in browsers, although the standardization process is still under development. As a result, there are several valid spellings and formats, and all of them must be covered accordingly. For example, for Internet Explorer 11, the Content-Security-Policy must also be set with the header X-Content-Security-Policy
.
The course of the development of the header Feature-Policy
with a renaming and the change of the syntax to the header Permissions-Policy
within two years is also an example of what can happen if headers are implemented and used prematurely. In my opinion, the new syntax is more complex, differs from the declaration form of other headers and the parallel support of two headers with different formats for the same purpose will do more harm than good to the adaptation of the header and thus to security.
I hope that a more thoughtful elaboration of the standards and the involvement of all browser manufacturers in the design and development of HTTP Response Headers will lead to more stability. Thereby I hope for a greater coverage in the use of these security relevant headers. At the moment we are observing a hesitant use of the headers, and the change policy as in the case of the Feature-Policy will not accelerate this. I hope that the introduction of the Origin-Policy will make it easier to set response headers, and that this will make it possible to configure all headers in one place. So that in the end more security relevant headers are used and the security of web applications is increased.
Our experts will get in contact with you!
Michael Schneider
Michael Schneider
Michael Schneider
Michael Schneider
Our experts will get in contact with you!