Skip to content
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

Proposal: Proof of Possession should bind key to identity & token #975

Open
haydentherapper opened this issue Jan 23, 2023 · 10 comments
Open
Labels
enhancement New feature or request

Comments

@haydentherapper
Copy link
Contributor

Description

Replay of a proof of possession (PoP) to associate a key with a different identity is currently possible (albeit difficult, since you must intercept the PoP somehow).

A proposal would be to generate a PoP over the identity of the token, the identity being the subject AND provider. Currently, only the subject is signed over. Furthermore, a CSR can be provided as a PoP, but Fulcio currently ignores the value of the subject. The CSR should sign over the subject and provider of the identity token (brought up in #863 (comment))

We can go one step further, and bind a specific token to a PoP, by including the token nonce. The signature would then be Sign(token.Subject, token.Issuer, token.Nonce) (for the CSR, maybe we'd include the nonce as an extension, implementation details TBD).

Thoughts @znewman01 @asraa @woodruffw?

Note: Not in scope is reuse of the OIDC token (which is a feature to some clients that cache OIDC tokens) or reuse of the signing key (Fulcio does not assert ephemerality, since some users may manage their own keys)

Lofty idea: PoPs are weaker than challenges, when a server presents a nonce to sign over, for replay prevention. The server could provide a challenge for clients to sign. This ends up looking a lot like ACME, so maybe Fulcio should implement the ACME protocol? This may be overkill, because users won't be hosting the challenge over HTTP/DNS. Needs more exploration.

@haydentherapper haydentherapper added the enhancement New feature or request label Jan 23, 2023
@woodruffw
Copy link
Member

This sounds pretty good to me! Anything that ratchets down the PoP is nice, even if intercepting the PoP is not a particularly likely attack scenario. +1 additionally to using the OIDC token's nonce in the PoP as well 🙂

One thing I want to make sure I understand: this has no meaningful effect on an attacker who intercepts the PoP (as (CSR, OIDC-token) and uses the intercepted OIDC-token to generate an entirely new CSR, correct? In that case the malicious CSR would be detected solely through the transparency log.

@haydentherapper
Copy link
Contributor Author

Correct! The transparency log should be sufficient for that case. Another option would be to persist token nonces to prevent reuse, but this would break some client use cases that want to cache and reuse tokens. Relying on the transparency log and checking for an expected number of identities in the log should be good.

@woodruffw
Copy link
Member

Correct! The transparency log should be sufficient for that case. Another option would be to persist token nonces to prevent reuse, but this would break some client use cases that want to cache and reuse tokens. Relying on the transparency log and checking for an expected number of identities in the log should be good.

Makes perfect sense! And agreed 100% on the CT log being sufficient 🙂

(This is making me again wish we could do key-binding on the OIDC token itself, but that seems like a remote possibility with the current IdPs...)

@znewman01
Copy link
Contributor

A proposal would be to generate a PoP over the identity of the token, the identity being the subject AND provider. Currently, only the subject is signed over. Furthermore, a CSR can be provided as a PoP, but Fulcio currently ignores the value of the subject. The CSR should sign over the subject and provider of the identity token (brought up in #863 (comment))

I think this is a great idea for both our PoP or CSRs. I also am in favor of shifting toward CSRs more generally from our PoPs.

Lofty idea: PoPs are weaker than challenges, when a server presents a nonce to sign over, for replay prevention. The server could provide a challenge for clients to sign. This ends up looking a lot like ACME, so maybe Fulcio should implement the ACME protocol? This may be overkill, because users won't be hosting the challenge over HTTP/DNS. Needs more exploration.

My dream here is to extend ACME to support a JWT "challenge type." There's an existing draft RFC that extends ACME for "End User Client and Code Signing Certificates" that has sort-of stalled. It alludes to but does not cover JWT challenges. I would like to (1) revive and finish that draft RFC, and (2) create a new RFC for JWT challenges, with which Fulcio could comply. (CC @joshuagl )

(This is making me again wish we could do key-binding on the OIDC token itself, but that seems like a remote possibility with the current IdPs...)

Would something like DPoPs get us there? See this analysis (you may need to join [email protected] for access).

Or are you talking about basically having IdPs operate as CAs?

@haydentherapper
Copy link
Contributor Author

Interesting RFC! Happy to chat more about it if you start work on reviving it.

@woodruffw
Copy link
Member

Would something like DPoPs get us there? See this analysis (you may need to join [email protected] for access).

Yep, I think so -- I was thinking of the <aud>?pkid=<H(DER(SPKI))> idea that came up in that recent "Sigstore without Sigstore" paper, but DPoP seems to be (from my reading) a generalization of the same key binding property!

@arianvp
Copy link

arianvp commented Jan 27, 2023

There is https://datatracker.ietf.org/doc/draft-acme-device-attest/00/. It doesn't use JWS signatures but WebAuthn signatures (The same that are used by Passkeys)

@arianvp
Copy link

arianvp commented Jan 27, 2023

https://solidproject.org/TR/oidc#tokens-id has a WIP spec for DPoP-id_tokens btw

@asraa
Copy link
Contributor

asraa commented Jan 27, 2023

Overall yes, I agree. I found it interested that only the token subject is signed over as proof of posession of the key, which means you can replay it with a different OIDC token whose issuer is different.

I badgered myself on this a lot, but it's only a very sneaky attack that requires a shady OIDC provider or squatting an account with the same subject in order to fool someone that you've also signed something that was ALREADY signed. Because you don't have private key access, you can't spoof a NEW signature.

Regardless, I still think it's important to do :) Because I don't like the idea of using the subject from the signed challenge, but the issuer from the OIDC token, which may mismatch.

I also am in favor of shifting toward CSRs more generally from our PoPs.

I think so too. I'm a little less familiar with the way this would work, but from my understanding Fulcio must verify the OIDC token, the CSR, and then ensure that the CSR subject and extension values match the OIDC token in order for this to work, right?

@haydentherapper
Copy link
Contributor Author

We aren’t verifying the CSR subject currently, it’s just a vehicle for the public key. With this proposal, yes, we must verify both the subject and an extension in the CSR match what’s in the token.

A small detail is extensions in CSRs are a bit of a pain to add in OpenSSL, but it’s doable, just need some examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants