I was debating whether or not to call Clear Site Data a Security Header but in the end I decided I would. During the use of a web app we can leave various pieces of data in the browser that we'd like to clear out if the user logs out or deletes their account. Clear Site Data gives us a reliable way to do that.
We potentially store all kinds of data on a user's device during the use of our site including cookies, cache, localStorage, sessionStorage, things like service worker registrations and much more. The Clear Site Data header gives us a reliable way to ensure that we delete any and all such data when we need or want to. Clearing cookies can be difficult unless you have an exhaustive list of all cookies that may be set and there's no reliable way at all to interact with the network cache in a browser either. Clear Site Data presents a reliable option to do all of this.
Clear Site Data
You can read the RFC for more details but I'm going to cover all of the basics here. If at any point you want to clear some data from the browser, say the users logs out or deletes their account, you return the Clear-Site-Data header and configure it to remove the data you'd like. There are currently 4 options on the type of data you can remove with the header, here are the snippets from the spec.
"cache" - The cache type indicates that the server wishes to remove locally cached data associated with the origin of a particular response’s url. This includes the network cache, of course, but will also remove data from various other caches which a user agent implements (prerendered pages, script caches, shader caches, etc.)
"cookies" - The cookies type indicates that the server wishes to remove cookies associated with the origin of a particular response’s url. Along with cookies, HTTP authentication credentials, and origin-bound tokens such as those defined by Channel ID and Token Binding are also cleared.
"storage" - The storage type indicates that the server wishes to remove locally stored data associated with the origin of a particular response’s url. This includes storage mechansims such as (
sessionStorage, [INDEXEDDB], [WEBDATABASE], etc), as well as tangentially related mechainsm such as service worker registrations.
"executionContexts" - The executionContexts type indicates that the server wishes to neuter and reload execution contexts currently rendering the origin of a particular response’s url.
"*" - The * (wildcard) pseudotype indicates that the server has the same effect as specifying all types.
When you'd like to clear one, some or all of these types of data from the browser then you simply issue the header on the response and configure it appropriately.
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"
Implementing on Report URI
I figured we had a great use case to deploy this on Report URI and test it out because we have user accounts that require auth, a logout feature and an account deletion feature too.
When a user logs out of their account, or deletes it, we now send the CSD header to make sure we've nuked anything that we may have left behind in their browser.
$this->session->sess_destroy(); $this->output->set_header('Clear-Site-Data: "cache", "cookies", "storage", "executionContexts", "*"'); $this->output->set_header('Location: /login/'); $this->output->set_status_header('302');
To make sure we get all types of data I've specified all 4 of the current types and the wildcard which should cover us for future additions to the spec too. That is one thing to watch though, if you use the wildcard today it may delete more than you expect in the future, so do bear that in mind! Here is our header being delivered on the logout page on my local test environment and this should be deployed to the live site by the time I publish.
Another thing to consider is protecting endpoints that deliver the CSD header against CSRF attacks. Hopefully things like your logout function already have CSRF protection but the combination of being logged out with CSD shouldn't really change too much, it's just something to think about. You can see above that our logout feature is a simple GET request but we do have a token in the path to detect and mititgate CSRF so make sure you do the same whether it's GET or POST.