With the October 2017 deadline approaching for compliance with Chrome's Certificate Transparency policy, sites can use the new Expect-CT header to determine if they're ready. It's easy to deploy and has a "report-only" mode so there's no risk involved. Here are the details.
CT has been around for a while but Chrome is going to require that all certificates issued in October 2017 and onward will have to be logged in CT logs or they won't be trusted. You can read more in my blog about Certificate Transparency, an introduction to get the details of how it will affect you and what your options are. This blog is about the new Expect-CT header that will allow you to determine if you are ready for the October 2017 deadline in Chrome. By deploying the header but not enforcing it you can get feedback from the browser to see if it was satisfied with the Signed Certificate Timestamps it received. If there are problems you can make sure they're resolved before the deadline and once you're ready to commit you can enforce the header to tell the browser to always expect and enforce CT.
The Expect-CT header
The spec for the header is available here, Chrome have a bug open for support here and you can check the Chrome Platform Status here. Deploying the header requires very little configuration for us as the host so let's go through all of the available directives.
enforce directive controls whether the browser should enforce the policy or treat it as report-only mode. The directive has no value so you simply include it or not depending on whether or not you want the browser to enforce the policy or just report on it.
max-age directive specifies the number of seconds that the browser should cache and apply the received policy for, whether enforced or report-only.
My favourite, the
report-uri directive specifies where the browser should send reports if it does not receive valid CT information. This is specified as an absolute URI.
Deploying the header
To start with, like any new mechanism, all sites should deploy this in the report-only mode to test the water and make sure it isn't going to cause failures. This means you should omit the
enforce directive and set
0. Here's an example:
Expect-CT: max-age=0; report-uri="https://scotthelme.report-uri.io/r/default/ct/reportOnly"
This policy is deployed in report-only mode and if the browser doesn't receive CT information that it's happy with, referred to as not being 'CT Qualified', rather than terminate the connection it will simply send a report to the specified report-uri value. Once you're happy that you're delivering SCTs properly and reliably you can start to enforce the Expect-CT policy and tell the browser not to accept certificates that are not properly logged in CT. Start this process of with a low max-age, a really low max-age.
Expect-CT: enforce; max-age=30; report-uri="https://scotthelme.report-uri.io/r/default/ct/enforce"
The browser will now cache and enforce this policy on all connections to your site for the next 30 seconds. This is a very short window, yes, but if everything goes completely sideways and you've overlooked something which results in your site going offline, you can remove the header and wait 30 seconds for your site to come back. This is great because you can pretend you have no idea what went wrong and not get blamed for anything! If all does go well then you can gradually increase this value as you gain more confidence. Perhaps a minute, then 10 minutes, an hour, a day, a week and so on.
I will be adding detection for this header to securityheaders.io shortly but for now it will not count towards your score. It's still early days for the header and the draft spec, which is why there is no scoring impact, but I do think that with the approaching requirement for CT we need to raise awareness. The sooner we can make site operators aware the better!
I'm hoping this well help site operators get out ahead of the upcoming CT requirements and make sure they're prepared!