-
Notifications
You must be signed in to change notification settings - Fork 84
Description
This create a TOFU (“Trust On First Use”), like an HPKP, into the CSP hashes (or all the system), this a concept. I don’t know how or if it can be implement in this way.
If a website got (fully) hacked the attacker can change the JS files and do more damage than that already had done. The attacker can change the header of the website and probably all the files. This allow to ignore any Integrity. I know that is not what this feature is intended to prevent at all.
But, consider something like:
Content-Security-Policy: script-src 'sha384-abc123' 'sha512-321cba' 'expiration-1506470400';
This will tell us that until 1506470400
(09-27-2017 in UTC) the website is only trust in sha256-abc123
and sha512-321cba
, the date should be in UTC.
I think this is useful if a website uses asymmetric encryption (also known as public-key cryptography), when user generate the key in client-side and use it to sign, when the server doesn’t have the information of the private key. So, one way (and must directly) for an attacker get this information is changing the JS to get this key, in this case the attacker already has control of it and can do that. In “my suggestion” the header will prevent this situation, because the hash of files is already known by the user, it's stored with him, the hash will not match with the modified JS.
This suggestion also has the objective to protect to MiTM, in some way. If an important data is keeped in localStorage (say an encrypted key-pair) and someone spoof the DNS (imagine if the end user trust in a malicious certificate authority, suppose the server don't use HPKP or the private key of the server was stolen). The attacker can redirect the user to his server this server can have a Javascript to read the localStorage, becausue is in the same domain. In my idea, the CSP will prevent it, because the CSP will remember the last parameters, so they not will allow to load scripts inline and only trust in some files, based in hashes. Because it will keep until the expiration
specified by the server.
How it works, in my mind.
This is TOFU, the user only trust in sha384-abc123
and sha512-321cba
until the date. When it reaches the expiration
the browser still checks the hash, nothing changes. However, the browser will not store these hashes anymore, the website can update it. If the browser receives a new header, after the expiration, like:
Content-Security-Policy: script-src 'sha384-xxx' 'sha512-yyy' 'expiration-1509062400';
The browser will start trust only in this new two hashes, so the browser will store it. That is how I think it will work. If the browser receives a new header before reach the expiration date of the old one the browser should ignore. We only trust at the first header valid. Is considering valid a header that have expiration date “bigger” than the current date. If the use never had access the website before and receives a CSP with a expiration
in the past the same behavior of the currently CSP 3 will apply, only check the hash but not store in it.
Some improve can be made, that I don't know how it will be set in header. Imagine something like:
Content-Security-Policy: script-src [https://site.com 'sha384-zzz' 'sha384-aaa' 'expiration-2017-08-30' 'start-2017-07-30’] [https://site.com ‘sha384-ccc’ ‘sha384-uuu’ 'expiration-2017-09-30' 'start-2017-08-30'];
I think it easy to understand the concept. Considering that today is 2017-08-27 the currently version of the website is using sha384-zzz
and sha384-aaa
, but the website already has an updated version developed and will publish it. They can ONLY update the files when the expiration ends, of course. So, they can send the hash of the new files before the updated version is published. This is useful to do when it is close ti publish the update. The website can inform what is the future files that will be available. In this case, between the
This have some problems:
- The client date/clock can be wrong, in past or future, this is the most important.
I don’t see a fix for it, this is really a problem. But Chrome already notify the user when the clock is wrong, but it is only for significant differences, I think. If the user syncs the time with a NTP and the attacker hacked it too, he can ignore theexpiration
. We need some secure way to get the time! - The server need to deploy the new file immediately.
This can be problematic in medium-large size website, to mitigate it you can create some “migration”, for example between 2017-07-30 to 2017-08-28 we trust inaaa
andzzz
and between 2017-08-28 to 2017-09-02 we trust inaaa
,zzz
,ccc
anduuu
and after only inccc
anduuu
. This middle step will create a “migration zone”. That should be useful for some servers that have cache of old versions or users with some minutes or hours of desync. - It will be make impossible to fix problems immediately, if some library on client-side have a secure problem or incompatibility (…) will need to wait until the next expiration date.
- I think need to create a limit, for instance the maximum can be six months (or one year), I don’t think a website will keep static forever.
This can apply for all parameters on CSP, but I think the hashes prevent most of cases, however it is a example. ;)