-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ambiguous CSR behavior: Fulcio accepts CSRs with email subjects that aren't emails #863
Comments
cc @di for visibility. |
I'd actually say this is working as intended. https://github.com/sigstore/fulcio/blob/main/fulcio.proto#L102 notes that all values, besides the public key, are ignored in the CSR. As for the proof of possession challenge, we don't care what you are signing over, just that you can generate a valid signature using a private key that can be verified with the CSRs public key. You could put total gibberish in the CSR if you wanted, as long as a) the public key is valid, b) the signature over the contents of the CSR is valid. FWIW, maybe there's an attack vector I'm missing, but in the other case of providing the public key, we probably could have designed this to just have the client sign a static string like the URL - What's being signed over doesn't matter, just that we can validate the signature. I considered having stricter validation that the CSR subject matches the subject in the OIDC token, but I decided it was an unnecessary error case. The only purpose for the CSR is to simplify key delivery for clients that can generate CSRs and don't want to deal with key encodings. |
Addendum: Some code snippets:
|
Thanks for explaining, and for the code snippets! It's good to know all of those fields are explicitly ignored. Yeah, I see no actual attack vector here -- it's just something that stood out to me during a review of our own code on Closing! |
From RFC 2986 (section 3) which describes PKCS#10:
I agree with the description of this as a "minor ability," but it does feel odd Reopening because I think we should reconsider and try to be consistent here, though I think we could get away with doing nothing. |
Agreed that it seems very minor. Also, since an attacker would already need to possess the OIDC token, the subject that's being signed over is already known. I don't see the threat vector with signing over a CSR without a subject. The other issue is this would be a breaking change to start enforcing the subject in the CSR. |
IIUC the risk is that I take your CSR without a subject and stick it next to my OIDC token. So I can get a cert when I don't control the corresponding private key. I don't know why this is useful to an attacker though. (Maybe that's exactly what you were saying.)
Do we have any information on usage here? I'd be curious to see whether anybody is actually sending CSRs. But I think I'd be okay with just documenting this better (API docs, inline comment, spec). |
CSRs are how |
Yea, I think for now the best we can do is better documentation. |
SGTM! I agree that the behavior here is not exploitable in its current form, so documentation seems appropriate. @haydentherapper if you can point me at the right doc, I'm happy to make those changes 🙂 |
Thanks! https://github.com/sigstore/fulcio/blob/main/fulcio_legacy.proto#L105 and https://github.com/sigstore/fulcio/blob/main/fulcio.proto#L105, and then regenerate the swagger docs with |
Thanks as well, will do momentarily. |
I noticed this while doing a read-through of
sigstore-python
's signing code: we currently construct a CSR like so:...where
oidc_identity.proof
is the value of either theemail
orsub
claim, depending on the kind of OIDC JWT being used.For OIDC JWTs that attest to email identities, this makes sense: we're sending a CSR with a
SubjectName
that's an email address. It doesn't make sense for OIDC JWTs that attest to URLs, since those aren't email addresses.However, it currently works for both:
sigstore-python
currently usesNameOID.EMAIL_ADDRESS
unconditionally, and Fulcio has been happily minting certs even when theSubjectName
is really a URL (like a GitHub Actions workflow reference).This probably isn't exploitable or dangerous in any way, since the CSR is otherwise well-formed and accompanied by a valid OIDC JWT and proof of possession for the signing key. But it's a little bit surprising, and suggests that Fulcio's CSR validation is a little looser than it should be.
IMO, there are (at least) two acceptable alternative behaviors here:
SubjectName
in the CSR entirely, and (after a deprecation period) have users set it to something well-known, likesigstore-csr
instead of an email address with an email OID. Then, explicitly document the behavior of re-deriving the subject from the adjacent JWT.SubjectName
, but enforce the correct OID type for the content of the subject. In other words:SubjectName
s that are tagged as emails should look like emails, URLs should beUNSTRUCTURED_NAME
or something similar, or maybe something custom.The text was updated successfully, but these errors were encountered: