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

What is the security model for non-extractable keys? #269

Closed
lucacasonato opened this issue Jul 21, 2021 · 2 comments
Closed

What is the security model for non-extractable keys? #269

lucacasonato opened this issue Jul 21, 2021 · 2 comments

Comments

@lucacasonato
Copy link
Contributor

We recently implemented CryptoKey and some related SubtleCrypto APIs in Deno. We intentionally do not yet support non-extractable keys because we have some open questions about the intended security model. The main questions we are hoping you can clarify is if non-extractable keys are meant as a security or an obfuscation primitive.

If they are meant as a security primitive in the age of timing side channel attacks like Spectre, it would not safe to store the underlying key material in the memory of the render process. All cryptographic operations and key storage would have to occur in a separate process. If it is only an obfuscation primitive, this approach would be ok.

Some more concrete questions:

  1. Is it expected that a compromise of the render process, or in process timing side channel attacks (Spectre) can extract "non extractable" keys?
  2. Is key material stored and accessible from the render process in Gecko, Chrome, and Safari?
@sleevi
Copy link
Contributor

sleevi commented Aug 13, 2021

The main questions we are hoping you can clarify is if non-extractable keys are meant as a security or an obfuscation primitive.

The dichotomy here isn't quite accurate, although I understand it's well-intentioned.

https://www.w3.org/TR/WebCryptoAPI/#security-developers attempts to address this overall concern, with this specific language:

Authors should be aware that this specification places no normative requirements on implementations as to how the underlying cryptographic key material is stored. The only requirement is that key material is not exposed to script, except through the use of the exportKey and wrapKey operations. In particular, it does not guarantee that the underlying cryptographic key material will not be persisted to disk, possibly unencrypted, nor that it will be inaccessible to users or other applications running with the same privileges as the User Agent. Any application or user that has access to the device storage may be able to recover the key material, even through scripts may be prohibited.

We can see, then, that the boundary being defined is with respect to script access. That is, if one has a CryptoKey object, then the spec today already guarantees they have access to an oracle that they can perform arbitrary operations on, but they cannot recover the raw key. However, it also holds that because a CryptoKey is by-design structured clonable, it means that if you have access to an oracle in one origin, you can always exfiltrate that oracle to another origin by virtue of postMessage and friends.

Thus, if one has the ability to execute script within Origin A (e.g. in order to perform Spectre attacks), then one can already exfiltrate the key to Origin B, by virtue of postMessage.

Some more concrete questions:

  1. Is it expected that a compromise of the render process, or in process timing side channel attacks (Spectre) can extract "non extractable" keys?
  2. Is key material stored and accessible from the render process in Gecko, Chrome, and Safari?

To the best of my knowledge, in all shipping implementations, key material is directly within the process memory space of the application. That is, "no hardening for Spectre".

Given the shape of the API at present, it's almost certain that the overheads involved would simply encourage developers to use WASM more for this case (which, to be clear, is an entirely secure and appropriate solution, modulo Spectre, for most use cases). As it stands today, developers already report that the task overhead (as well as potential thread switches to ensure non-blocking of the JS main thread) are performance bottlenecks - IPC overheads would only further exacerbate this.

@lucacasonato
Copy link
Contributor Author

Thanks for the detailed answer @sleevi!

We will go for the same model then, where key material is directly within the process memory.

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

No branches or pull requests

2 participants