Open Lukasa opened 10 years ago
CERT_URL = "https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt"
, seriously?
There are so many things wrong with that.
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS https://wiki.mozilla.org/CA:IncludedCAs https://mozillacaprogram.secure.force.com/CA/IncludedCACertificateRepNSS
As you noticed, you're not verifying/pinning the certificate.
I am verifying the certificate in the literal sense: it must be a certificate that is valid for the domain. What I'm not doing, and we agree on this, is validating that it's the specific certificate I expect, which is generally referred to as pinning, not verifying.
There is likely no DNS verification either.
That's true, but is out of my hands.
You don't want to download tip w/o manually verifying the content, please use a manually updated commit hash, and if mercurial supports gpg signed commits, check for that.
Mercurial has extension support for GPG signed commits, but Mozilla aren't using it. Even if they were, that would require that Mozilla provide a whitelist of the allowed authors for changes to the certificate bundle, which they don't.
In the absence of these things, downloading a verified commit hash does not meaningfully reduce the threat surface at all. A malicious entity that does either of the two things you suggested ("hack the mercurial server" or "hack Mozilla ops and commit to the repo") is just as capable of compromising the repository history or the direct HTTPS download of one of the hashes: without any form of cryptographic verification of the original Mozilla change I have no hope of defending against those attacks.
This service necessarily trusts Mozilla: it has no option but to do so. Anyone downloading the Firefox browser is exposed to the same set of risks.
I download a bundle I must be able to track it down to a verified Mozilla commit.
I got confused here because you started talking about certifi.io. With the certifi packages you should be able to achieve exactly this. Each bundle is versioned the day it was produced: you should be able to validate that the PEM bundle corresponds to the file Mozilla has on their server. You would of course have to do this anyway, because there is no way for you to validate cryptographically that the PEM produced corresponds to a given Mozilla commit without parsing both files. Once you've got a tool capable of parsing PEM and NSS cert bundles, and you're sufficiently defensive to want to use it, it begins to become unclear to me why you're using mkcert (or certifi) at all: you can generate the things you need yourself!
However, building up a larger chain of trust is difficult. Even if Mozilla signed their commit, I'd have to validate that mkcert.org produced the PEM file validly and safely. I cannot do that in a way that is cryptographically sound: the server at mkcert.org can always lie about what inputs it used to produce a given PEM file. The only way to validate that mkcert.org is safe is to examine the PEM file yourself, and if you're skilled enough to do that you have a very limited need for any other tool.
I believe that cert pinning against Mozilla's website is a good idea: that's why I originally opened this issue at all! But there is no fully trustworthy way to obtain this certificate bundle that defends against the attacks you listed. At some point, someone has to trust that some set of the machines and people involved in the transaction are good actors.
If you don't trust that Mozilla is uncompromised, then you shouldn't use any tool that generates a PEM file from Mozilla's trust store. If you don't trust that I and mkcert.org are uncompromised, then you shouldn't use any tool that gets its output from mkcert.org. If you don't trust that the certifi team are uncompromised, you shoudn't use certifi. If you don't trust that PyPI is uncompromised, you shouldn't download the package from PyPI.
I am doing my best with what I have. I'm sorry that it isn't good enough for you. =(
Mercurial has extension support for GPG signed commits, but Mozilla aren't using it.
That's a pity, maybe the NSS repo they're using provides a verifiable source, I mean someone should offer this information in a way, that's more secure than a repo host. How about this for example? https://mozillacaprogram.secure.force.com/CA/IncludedCACertificateReport
I got confused here because you started talking about certifi.io. With the certifi packages you should be able to achieve exactly this.
From my perspective of view it looked like certfi.io and it's underlying mkcert.org are the upstream part, and the language packages are the consumers. And you're right the versioned and hopefully reviewed packages provide this information.
I am doing my best with what I have. I'm sorry that it isn't good enough for you. =(
I really like the idea, that's why I want to build a D package ¹ for it. I was just surprised that the website service doesn't provide me with more guarantees, e.g. it would be problematic to just download and package the bundle from mkcert. Rather I'll have to semi-automatically verify the certs against various other sources. The latter is quite some work, guess I was hoping that you already did that, but maybe we can find a more trustworthy source from Mozilla/NSS that would spare us the step. Have you ever tried to contact them and asked for a signed certificate list?
Have you ever tried to contact them and asked for a signed certificate list?
Nope: when I started doing this I had basically no contacts at Mozilla. Now, however, that's not true.
I wonder if it's worth me getting in touch with some Mozillans I know and asking them whether there's a way we can get hold of verified copies of the trust bundle. Even just as minor as GPG signed mail from a key that we trust would be enough.
I agree though: I trust mkcert because I do from time to time spin up a local copy of mkcert and verify it against the remote one, and because the git history of python-certifi means I can easily see what certificates are added/removed with each change. But it's definitely harder for someone else (like you!) to have the same trust: I'm just a person at the end of the keyboard to you!
Let me see if I can ping some people I know at Mozilla about getting access to a better source of trust from Mozilla.
mkcert.org is a bad idea in the first place. This is by design a man-in-the-middle. Whatever how the source of mkcert.org is reliable, no client can be sure that what mkcert.org serves now or in the future is not corrupted from the original Mozilla source.
That would be why the source code is available here, for you to build and run yourself locally if you want to.
Software to run locally are CLI or package to include in an app.
Web APIs available as public services are designed for misuse because they provide conveniency (over security) to lazy developers. And misuse there is: people build software libraries relying on the online instance of mkcert.org.
Check the commit log: I wrote that certifi software. I'm running both bits of infra, and so am quite capable of verifying the result. I think it's reasonable that I'm allowed to trust myself.
We don't want to expose ourselves to the NSA MITM-ing us. We should pin Mozilla's cert.