Protect logins using temporary HPKP

A few days ago I got a really smart idea how I can deploy HPKP but only for the vital parts(login, control panel and admin area) on my forum. Why would you do that? Well, HPKP is very risky if you really want to protect your members because if you for some reason loose your certificate, visitors will not be able to visit your website for a long time(if you (hopefully) selected a very long max-age).


This is the result:

  1. Create a way to generate the HPKP-header. Because you must have a backup-certificate you can just ignore this because this HPKP-rule only need to affect the leaf(in fact, it's safer that way). In PHP this is easy:
    header('Public-Key-Pins: pin-sha256="AG5Ok0nKLXEtgeGyKhookllWeaiyaZZT5h9g2d4HAPE="; pin-sha256="SWEHACKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="; max-age=600');

  2. On the login and/or register-page you set an iframe to that file, like this:
    < iframe src="https://swehack.org/hpkp.php" width="1" height="1">

  3. Now, the POST-request(because you signed in/up, remember?) will now be protected with HPKP and be valid for only for how long you choose to make the HPKP-rule to be valid for. Because the HPKP-header no longer will be preset after login the max-age will not be updated.

Here's a picture!


Why?



Facebook does something similar. Facebook has a very short max-age(500 seconds) and this is fine I guess but remember that the longer the max-age, the safer and how long is really a Facebook session? Depending on your site you should set the approximate max-age.

This method is great because then you can safer use HPKP and only protect what's needs to be protected. Also, in my case where I run a forum, most of the visitors are actually not logged in(90% read, 10% are logged in and active) so if I really screwed up and lost my certificates it will almost have no effect because non-logged in visitors will be able to reach the site.

EDIT: Yes, you can send a header for a specific URL in the most httpd's. Here's for Apache:

SetEnvIf Request_URI "/ucp.php?mode=login" custom_header
Header set X-FOO BAR env=custom_header