-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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.createCipher should not work with AES-CTR #13801
Comments
cc @nodejs/crypto |
It appears this problem is not uncommon. This search gives ~500 JS files. Some large repositories I found that use this unsafe code (haven't checked for exploitability):
And then there's this blog post: http://lollyrock.com/articles/nodejs-encryption/ |
Similar arguments apply to many AES ciphers. It is strongly recommended to always use a random IV, no matter which block cipher mode is used. Even though the problems arising from using a constant IV are more severe for CTR, there are serious implications for other ciphers, e.g. OFB. Non-streaming modes such as CBC are less vulnerable, but still benefit from a random IV. Maybe @shigeki has some more insights. |
There is one, isn't there? Or am I misunderstanding you?
Or do you specifically want to call out AES-CTR? Like @tniessen mentions, it's not specific to that cipher. |
We might want to visually and verbally highlight the security implications of using |
Yeah, agreed, that was my issue -- "recommended" is a bit far from a warning. This does become a problem for other modes as well. Maybe it's worth talking about modifying the API to only have Of course, there are other issues with people blindly using CTR besides the IV, but this seems like the biggest one. |
@bnoordhuis I think we should print a warning similar to what we do for deprecated APIs. This warning could be disabled by either env or command-line arguments. |
@indutny What about ciphers which do not use an IV such as ECB mode? It is perfectly fine to use |
@tniessen I absolutely agree, this has to be applied selectively. |
I agree 100% that IV generation should be left to the API consumer, given that this is exposing mostly low-level cryptographic primitives. Furthermore, there should be a strong warning in the API documentation that IVs are nonces and should be nondeterministic and uniformly random. The IV-less |
I think we can agree that the behavior of |
Printing warnings on unsafe use isn't a bad idea but -- Socratic method follows -- if the motivation is to protect unskilled programmers against themselves, where do we stop? Should ECB ciphers print a warning? What about obsolete ciphers like DES and RC2? Should we just turn on FIPS mode unconditionally and call it quits? It does all of the above and more. |
@tniessen Arguably, you should need to explicitly "break the seal on the warranty" to use something like ECB mode. Ideally, the APIs here would be designed to guide the user to the right decision by default. Encryption functions should optionally take an IV, and return an Likewise, AES-128-GCM should be the default should no cipher be explicitly chosen (this may be the case, I'm just an infosec person leaving a drive-by comment). If the user doesn't provide a tag when decrypting authenticated modes like GCM, fail. It should not be considered acceptable in 2017 to provide APIs that point a gun at your foot by default, with an easily-missed comment in the documentation recommending that you do more work to aim the gun away before pulling the trigger. Aim the gun away from the foot by default. Default to having the safety on. Require explicit intent to disable the safety and to aim the gun at the foot. It is not reasonable to expect anyone who is not a cryptographer to use |
@stouset Volunteering? |
I think that emitting warning is a good idea. This is a side effect of the current |
If there's no safe way to use a crypto API, why would you retain it? There's no compat issue here with any mainstream system, and any system that depends on this behavior has a grave security flaw. |
@bnoordhuis Volunteering my advice on the design of cryptographic APIs, sure. @tqbf My point exactly. It's not wrong to expose the raw AES block cipher, or to allow an all-zero IV. Sometimes your users have to integrate with existing broken systems, or are genuinely qualified to build systems out of these these sharp-edged tools. But these are specialized use-cases, and should not be the easiest or default way of using the API. |
That's infosec for you... |
My sincerest apologies for contributing to the extent that I'm qualified. I can assure you it will never happen again. Perhaps if you'd had the foresight to make this mistake in a project using Rust, Ruby, C, go, or one of the other languages I'm actually comfortable committing crypto-related code in we could have actually made a difference here. |
I hope you can see it from my point of view. Someone posts a strongly opinionated comment and then when you ask them to follow up, no dice. It's not just you. Security-related issues have a habit of attracting random people with Big Opinions, generating lots of heated discussion, and then... nothing. Off to another bug tracker to fight the good fight, presumably. It's frustrating. |
It is important that Node.js not make it easy to instantiate CTR mode with a deterministic nonce/IV. That's not a "Big Opinion"; it's a cryptographic fact. It is critically important that stream cipher keystreams never repeat, and deterministic nonces/IVs lead to repeated keystreams. This is probably one of the oldest practical vulnerabilities in cryptography. |
I have an alternate proposal for a |
I can assure you it's equally as frustrating for cryptographers to discover yet another open source project with a footgun crypto API. And further frustrating when the response to this being pointed out is that there's a warning in the documentation, there are surely users somewhere who want a footgun, and if we just log a warning everything will be fine. I am happy to contribute in the form of API design. If you don't think that's valuable, consider that the current API has resulted in (naïvely) 350 instances of misuse and 100 instances of correct use in public GitHub repos. Fewer than 25% of developers have used the current API safely, and that's generously assuming all 100 Edit: Modified the search terms to hopefully get a more representative result. |
Not to undermine your point but that looks like the same two or three files cloned 2,500x. |
Updated the searches. There's still some copy-pasted files, but that doesn't necessarily speak against my point. Vulnerable code cloned to multiple repos is just as bad as vulnerable code hand-rolled in those same repos. |
That's not really accurate. The response to
The real response to these things is "could you submit a PR?" Node could really do with some more people with the expertise to look at and fix crypto issues. |
As pointed out by other people, there is no way to use the current implementation of crypto.createCipher safely. |
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: nodejs/node#13801 PR-URL: nodejs/node#13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: nodejs/node#13801 PR-URL: nodejs/node#13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: nodejs#13801 PR-URL: nodejs#13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
…r, likely after [this](nodejs/node#13801) came out
Node should not allow calls to
crypto.createCipher
to succeed when the AES mode selected is CTR. AES-CTR is fundamentally broken when an initialization vector is used twice, andcrypto.createCipher
will always generate the same initialization vector for the same key, socrypto.createCipheriv
needs to be used.In the short term, there should probably be a warning about this in the function's documentation.
Posted because of HainaLi/horcrux_password_manager#1.
The text was updated successfully, but these errors were encountered: