life off the chain
A few notes about gathered experiences with https certs not part of the traditional chain.
The simplest way to deal with an untrusted site is to add an exception. There are some quirks, however.
Most browsers will ignore additional headers like HSTS. It’s a little weird, because if I indicated a desire to see https, regardless of cert, that should be interpreted as a positive indicator that I really want the https version, right? I think the motivation is to prevent a user from accidentally DOSing themselves if the https site goes away. HSTS is supposed to be under the control of the site owner, and if the cert is invalid, maybe it’s not the site owner, so ignore it? The eternal conflict between site owners and end users for control over how things work. (I did somehow trick Chrome into marking my site as HSTS required, but I think that was a bug.)
Safari would refuse to load resources cross origin. I noticed this when using a static. subdomain for some images. The exception for the static site was in place, and it could be browsed normally, and once loaded into browser cache an image would be displayed on other sites, but it was cranky about making cross origin requests. Kind of curious.
Chrome will only remember exceptions for a few days. Then you get the scary warning again. Their explanation is that maybe users will accept a cert by accident, and there’s no easy or obvious way to undo that, so the solution is to just automatically undo it. That’s kind of strange, no? Why not make it easier to manage exceptions? If we don’t want to condition users to blindly click through warnings, maybe don’t keep repeating the same warning over and over. If it’s necessary to remind users that a site is off chain, the message could be a reminder, but at least make it look very different than the typical under attack warning.
At least browsers let you manage exceptions. A number of other programs, including but not limited to RSS readers, offer very little control over cert checking. This poses some difficulty.
The other approach is to install a new root cert. This works better, where it can be done, but also has a quirk or two.
Discovered a little too late that LibreSSL didn’t support name constraints for a whole domain. That’s kind of embarrassing. Slipped through my testing because the early trials didn’t use name constraints. And then, for a number of reasons including shaky support for SNI in python 2, my “production” environment generally sidesteps cert validation entirely. But better to find the bug now. Maybe someday name constraints will be relevant.
When adding a custom root, HPKP is disabled. Maybe. This is necessary to allow interception to work (in those scenarios where you want interception to work). The precise wording is kind of unclear, however. From MDN: “Firefox and Chrome disable pin validation for pinned hosts whose validated certificate chain terminates at a user-defined trust anchor (rather than a built-in trust anchor). This means that for users who imported custom root certificates all pinning violations are ignored.” The first sentence and second sentence aren’t equivalent. If I import a trust anchor with constraints, are pinning violations ignored, as per second sentence? One would hope not, and the first sentence would seem to indicate that. It’s hard to explain how things work when we keep piling exceptions on top of exceptions.