-
Notifications
You must be signed in to change notification settings - Fork 122
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
Use of predictable RNG #178
Comments
This temporary file library is equivalent to
This is one of those cases where you need to understand the threat-model. There are many theoretical attacks that simply aren't worth the effort to guard against:
Basically, if an attacker is in a place where they can exploit this issue, you likely have bigger issues. Also note, python, golang, and C all behave the same way (use non-cryptographic randomness for performance). If you want to improve the situation, I'd be happy to accept a patch that re-seeds the random number generator with system randomness if it fails to create a temporary file after some number of tries. edited: My original comment made statements about security "experts" which could have been taken as a comment about security researchers in general. This was not my intention, nor was it relevant. |
I disagree with 1., "many" can be three, depending on the RNG. I agree that 2. is a problem anyway, and that ideally the temporary files should not share a namespace with other applications, but temporary files are often used like this. Non-cryptographic randomness is not a performance advantage, CSPRNGs have comparable speed, because they are optimized for SIMD while the non-CSPRNGs are not. Non-CSPRNGs are simpler, not necessarily faster. The scenario you are mentioning (DoS) is the least concerning. I would be much more concerned about an attacker manipulating file permissions and content, or escalating privileges. This can be avoided with flags like What is the motivation for not using a CSPRNG? Compilation time and code complexity? |
This is the main reason this crate exists. It handles all the platform quirks around
The only thing affected would be named temporary files/directories on Linux where the user is using the shared /tmp directory directly.
Complexity and dependency weight. Performance isn't really an issue given that the syscall cost to create a file will likely dominate in most cases. |
Can this crate be used in production where the filenames must be unpredictable ? If the crate does not guarantee predictability then it perhaps should simply be documented as such. This crate is advertising itself as:
Thanks |
(got sent here from the advisory-db link)
There's no method in the In my testing, on linux at least, Especially since you're doing a syscall and probably file IO afterwards, the perf of getting entropy is likely fine. |
Yes, it absolutely can. Same as python and go which use the same randomness function for temporary files. Worst-case, there's a DoS vector. But if you have some untrusted application that can create many files with chosen names in a shared temporary directory of temporary files, you this is the least of your concerns. Security is all about understanding your threat model and making trade-offs (performance, complexity, etc.).
A call to |
Cool thanks for clarifying - We are pretty practical at RustSec and we have recommended your crate over others - We recently had to file advisory on https://rustsec.org/advisories/RUSTSEC-2018-0022.html Thanks for working on a crate that focuses on security and portability 🦄 |
Using |
|
The best solution is probably to read, maybe, 1k of bytes into a thread-local buffer, then draw randomness from that until we run out. |
- Instead of setting up a predictable userspace RNG, we get unpredictable random bytes directly from the OS. This fixes Stebalien#178. - To obtain a uniformly distributed alphanumeric string, we convert the the random bytes to base64 and throw away any letters we don't want (`+` and `/`). With a low probability, this may result in obtaining too few alphanumeric letters, in which case we request more randomness from the OS until we have enough. - Because we cannot control the seed anymore, a test manufacturing collisions by setting the same seed for several threads had to be removed.
Unfortunately, that method is slightly biased and does not result in a uniform alphanumeric distribution. |
Hm, that slightly biases the first 8 characters. |
Modulo bias would be arguably Fine here since we only need a value that can't be perfectly predicted consistently, not a value that can be predicted even slightly better than average. |
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
Re-seed thread-local RNG from system randomness if we run into a temporary file-name collision. This should address the concerns about using a predictable RNG without hurting performance in the common case where nobody is trying to predict our filenames. I'm only re-seeding once because if we _still_ fail to create a temporary file, the collision was likely due to too many temporary files instead of an attacker predicting our random temporary file names. I've also reduced the number of tries from 2^31 to 2^16. If it takes more than that to create a temporary file, something else is wrong. Pausing for a long time is usually worse than just failing. fixes #178
This library recently switched to non-CSPRNGs (see #141 and #162), which are inherently predictable based on observations of their output. Doesn't this make the library vulnerable to attacks listed here, because the generated filenames can be predicted?
The text was updated successfully, but these errors were encountered: