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

Should response encryption be required #109

Open
RByers opened this issue May 1, 2024 · 11 comments
Open

Should response encryption be required #109

RByers opened this issue May 1, 2024 · 11 comments

Comments

@RByers
Copy link
Member

RByers commented May 1, 2024

Related to #49 and several other discussions we've had: do we want to say that the response must always be encrypted (and if so, by which algorithms), or are we OK leaving that as optional?

@OR13
Copy link
Contributor

OR13 commented May 1, 2024

under what threat model, does encrypting the response defend against?
can we pose some hypothetical attacks?

@RByers
Copy link
Member Author

RByers commented May 1, 2024

FWIW , on the one hand I think there's a good argument for saying this is the wrong layer of the stack to make such a requirement. Just like with, say, communication over custom schemes, the definition of a low-level communication protocol can't really impose such constraints on the data sent in that protocol. But, on the other hand...

under what threat model, does encrypting the response defend against?
can we pose some hypothetical attacks?

One I believe is legit is a malicious browser extension:

  • User has installed a browser extension which offers some benefits that requires script injection on all websites
  • This extension was hacked or bought by a bad actor and not yet discovered / banned from the extension store
  • Extension injects script into every page to harvest PII including passwords etc. It also hooks the digital credential API to harvest any response through that channel.

Another less clear threat is XSS-mitigation:

  • Legitimate website has a cross-site scripting bug that enables an attacker to run script on the page, without being in control of the web server
  • Such script behaves like a malicious browser extension - hooking API calls and sending the data from them to an attacker-controlled server

Maybe more important is the cross-device flow:

  • User has a secure mobile device with their wallet app and no malware
  • User uses their Windows PC to access a website that requests a digital credential presentation
  • They complete the request using the cross-device flow (not yet part of this spec, I know) from their mobile device
  • Malware on the windows machine is scraping PII from the browser (possibly via a malicious extension, or other mechanisms).

There's also a defense-in-depth argument for browser bugs:

  • Attacker has a RCE vulnerability for the user's browser, but no sandbox escape vulnerability (this is not uncommon in the world of browser security - sandbox escapes are the really hard ones IMHO).
  • Attacker manages to buy display ads and runs their attack from script in those ads on lots of websites
  • When successful the attack searches ram for the browser web contents process for any PII and sends it to an attacker-controlled server
  • User completes a credential presentation on a website that is also serving ads inside a sandboxed or 3P iframe and gets hit by this attack.

@bc-pi
Copy link

bc-pi commented May 1, 2024

On the layer of the stack point it might be worth the observation that OID4VP (and its nascent profile for this API) allows for but does not require response content to be encrypted. And it all kinda happens at that layer of the stack. A public key in JWK (RFC 7517) format can be conveyed in the request and the corresponding response would contain a compact serialized JWE (RFC 7516) with the actual response data encrypted to that public key.

@msporny
Copy link
Contributor

msporny commented May 6, 2024

Should response encryption be required

No, it shouldn't be required, but it should be possible. There are use cases where encrypting the response don't make sense, like delivering a Verifiable Credential for a Movie Ticket (or any sort of unlinkable presentation), for example.

Many of the attacks you outlined are "the website environment has been compromised" attacks, and once that happens, all sorts of terrible things are possible. Yes, we could do defense at depth, but then we elevate all use cases to use the maximum amount of security possible (encrypt everything), which makes the APIs far more difficult to use for simple things.

One of the arguments here is that the DC API is more secure than the alternatives, but now it seems like we're saying it's not secure unless we E2E encrypt everything. It's like saying that subresource integrity should be mandated for all websites -- doesn't make much sense as most of the websites out there operate just fine without subresource integrity... though, it's nice to have it available when you really need it.

As @bc-pi said, whether or not the low-level stuff is encrypted or not is largely up to the underlying query/response format. The DC API should enable encryption without mandating it for everything.

@samuelgoto
Copy link
Collaborator

I think there's a good argument for saying this is the wrong layer of the stack to make such a requirement

I think this is the key thing to answer: if we answer this on the positive (i.e. that this is the wrong layer of the stack), I think it clarifies everything.

On the layer of the stack point it might be worth the observation that OID4VP

I think that's the way to think about response encryption: not a concern for the browser, a concern for the protocol running on top of it, e.g. OpenID4VP.

@jogu
Copy link

jogu commented Jun 3, 2024

I agree with the comments above that this is the wrong layer of the stack to deal with this.

Even if we did want to do this at this level, in practice I believe we can't technically enforce encryption at the Browser API level, and encryption by itself doesn't defend against some of the attacks above (an attacker that can obtain the credential response may also be able to manipulate any encryption key passed in the request). A signed request can prevent that, but that needs much more infrastructure and all that is covered at the OID4VP level.

@RByers
Copy link
Member Author

RByers commented Jun 3, 2024

One note from the call today, it sounded like there was no disagreement with at least having a statement in our spec along the forms of "implementations which pass PII in the response MUST encrypt that information to the verifier in some fashion". The debate is just about how much stronger than this we can be, right? If we can't get anything any stronger, is anyone opposed to something like the above being the min-bar in the spec?

@jogu
Copy link

jogu commented Jun 3, 2024

One note from the call today, it sounded like there was no disagreement with at least having a statement in our spec along the forms of "implementations which pass PII in the response MUST encrypt that information to the verifier in some fashion". The debate is just about how much stronger than this we can be, right? If we can't get anything any stronger, is anyone opposed to something like the above being the min-bar in the spec?

I don't particularly object to a statement like that, but I think:

  1. We should be clear about what threat(s) we are trying to prevent (this doesn't need to go in the spec, but we should be clear which of the attacks listed in Should response encryption be required #109 (comment) we think this statement solves).
  2. We should be clear in the spec that there are common attacks that are not prevented by encrypting to a key that's in a parameter passed to the browser API and has no further proof of authenticity of the key

@martijnharing
Copy link
Collaborator

As discussed here, there is no disagreement to have response encryption as a mandatory item. As such, both RPs and wallets will need to implement support for response encryption. Since all protocols that use browser API need to define response encryption, defining it on the browser API layer instead of the underlying protocol has multiple benefits:

  • It reduces implementation complexity for wallets and RPs when supporting multiple protocols.
  • One of the goals of response encryption is ensuring proper binding between the response message and the session context. This is partly specific to the browser API, so designing it as part of the browser API ensures that the details are properly considered.
  • It addresses [spec] add statement about responses with PII MUST be encrypted #124 in a very simple manner, by mandating the use of the response encryption mechanism in certain scenarios.

Concretely, within the browser API we would define the cryptographic details to derive the encryption key and the encryption operation used by the wallet to encrypt the response data blob. Underlying protocols can provide additional information for trust in the encryption key material, this can be out of scope for the browser api.

@jogu
Copy link

jogu commented Jun 12, 2024

As discussed here, there is no disagreement to have response encryption as a mandatory item. As such, both RPs and wallets will need to implement support for response encryption.

TLS is a potentially suitable alternative that may avoid the need to explicitly implement response encryption in both the RP & the wallet, so I don't think the 'RPs need to implement support for response encryption' part is agreed on yet, and is I believe why Tim's suggested wording in #124 was carefully chosen.

That aside, I think encryption at the browser API level increases implementation complexity if you consider the overall position, because the key used and the trust in the key are now spread across two different layers, and it seems quite likely that passing the key at the browser level means the key needs to be passed twice (once at each layer).

Spreading across layers (in particular passing the key in a very different way to how the trust in the way is communicated) potentially makes it more likely that wallets fall to implement the check that the key has been attested, and increases the divergence between the browser API and non-browser API code paths (which in my opinion is a bad thing).

An encryption key at the browser API is also a potentially unnecessary complexity if the credential is returned to the verifier without it passing through the browser API (e.g. the 'direct_post' mode in OID4VP).

There is also the issue mentioned on the (I think) previous call that protocol designers may be lured into a false sense of security if encryption is present at the browser api level.

I don't think I fully understand your second bullet; I don't think any of the existing issues suggested using encryption as a session binding mechanism, or I missed it. If this is essentially an advantage of having encryption at the browser API level could you expand on this point please?

@Sakurann
Copy link
Contributor

Sakurann commented Aug 1, 2024

As discussed here, there is no disagreement to have response encryption as a mandatory item.

Reading this thread for the first time, I am not sure where this conclusion comes from? I am sure I have missed relevant discussions on the call, but sounds like there are still opinions that this is a wrong layer to enforce encryption, nor it is possible to enforce encryption at this layer...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants