-
Notifications
You must be signed in to change notification settings - Fork 28.2k
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
crypto: freeze crypto module to prevent malicious code from controlling key generation #31442
Comments
What kind of malicious modules are you worried about here? I don’t want to sound dismissive, but if you’re running untrusted JS code, it can do anything like this already, whether it makes changes to builtin modules or not. (For example: Any module can observe what the current JS code does through the And in particular |
I guess @nodejs/security-triage would be the team to ping here? |
I think the same thing could be said for monkey-patching any part of node core, not just |
I figured this might be the response, so I'll try to make a good argument for this... The security implications here are different from an attacker monkey patching another part of node core. Altering any other part of the core API is short-lived. For example, say someone monkey-patched the In the NPM ecosystem there have already been a couple of attacks trying to steal bitcoin keys by monkey patching wallet modules.
I don't think anyone is advocating running untrusted code. I'm specifically referring to the context of an attack -- a situation in which untrusted code is run against the user's wishes. edit because I want to emphasize the severity of this issue: The attack I described works without any network connection at all, meaning that even if someone were being safe and doing signing/generation on an air-gapped machine, their keys can still be stolen. There is no other situation in node.js where data can be stolen from a user without a network connection. |
Stealing data sent/received over http(s) comes to mind.
I don't understand this. Against the user's wishes? It sounds like you're running untrusted code from the get-go then? I also don't understand the use case being described. If someone is stealing keys, at some point they would need to be transferred to the attacker no? |
Instead of monkey-patching a frozen crypto.randomBytes, monkey-patch fs, and whenever a PEM key is written.. replace it with a fixed one. Or, monkey patch http, and replace the output. Or, monkey-patch the function that is calling crypto.randomBytes, and replace it. This strikes me as more giving the appearance of security without substance. On the other hand, anything that makes attacks even slightly more difficult could be described as "defence in depth". But there's a fine line between DiD and snake-oil in depth. |
See my edit as I clarified this. This attack works without a network connection. There is no other high-stake data theft possibility that works without a network connection.
There have already been attacks like this in the NPM ecosystem. I'm referring to situations like this: https://github.com/bitpay/copay/issues/9346
No. If the attacker seeds their malicious RNG with a predictable key, they know every key the user will generate. |
While I understand the sentiment, security measures like what you're proposing are very easy to defeat with It doesn't make attacks materially harder and would only give a false sense of security. |
I suppose I see it differently: I understand node is not meant to be a secure under these conditions, but I want attacks to be as high-effort as possible. I know there is no perfect solution for this issue, but I see solutions as a red herring. I never look for solutions, only mitigations. This is a one-line mitigation to get rid of some low-hanging fruit. Anyway, it seems like people are not on board with this. I guess I'll be figuring out different mitigations for my own code. As an aside: I was previously directly calling out to Feel free to close. |
Currently, a malicious module can do:
A more sophisticated version of this attack would seed a PRNG with a predictable key to make the resulting bytes look random.
I feel like
randomBytes
is particularly vulnerable here, but this also applies to any key generation method as well.If I'm supposed to be generating unpredictable secret data, I want to be 100% certain that
crypto.randomBytes
is calling out to the OpenSSL RNG, not user code.The solution would be a one line fix of
Object.freeze(crypto)
.I realize this is a breaking change, and existing code may be using this "feature" for non-malicious reasons, but the change here is probably worth the breakage.
The text was updated successfully, but these errors were encountered: