Open bf opened 3 days ago
@bf Did you reach this in a practical use-case, or is this purely synthetic?
Purely synthetic.
I've been working with rust for a couple of weeks and found some interesting edge cases concerning security risks arising from rustc
, rustfmt
, rustdoc
and macros. Security team said The threat model of the Rust compiler assumes that the source code of the project and all the dependencies being built is fully trusted
and asked me to file a bug report for this specific issue in order to improve rustc
robustness.
IMO there are several by-design security risks for developers using rust right now. When you build software with rust, you're unknowingly accepting these security risks. The stance of rust security team elegantly avoids these risks by stating they are out of scope because all code is trusted.
I'm currently trying to document these security risks, so they can be explicitly accepted by developers using rust, and maybe nudge the rust security team towards implementing more security controls and fail-safes so rust follows a more defense-in-depth approach.
I have documented how rust users can be exploited by compiling untrusted code with rustc
(expected from many other languages, but could be improved with rust), by generating documentation for untrusted code with rustdoc
(unexpected, should not happen imo), and of course by running the compiled untrusted code (expected).
But getting all your data stolen by simply formatting code with rustfmt
would be both an unexpected finding and the cherry on top, so please let me know if you think this issue is exploitable ;)
I'll be sharing a write-up soon.
@bf I think there's some confusion regarding what "security" we're talking about here.
I've been working with rust for a couple of weeks and found some interesting edge cases concerning security risks arising from
rustc
,rustfmt
,rustdoc
and macros. Security team saidThe threat model of the Rust compiler assumes that the source code of the project and all the dependencies being built is fully trusted
and asked me to file a bug report for this specific issue in order to improverustc
robustness.
I can only speak for rustc
, but we assume that all source code that you sent to rustc
is fully trusted, i.e. vetted by you. Please do not conflate "security" versus robustness against arbitrary inputs that might crash rustc
due to resource exhaustion, typically code that users might write or generate.
For resource exhaustion crashes, we typically prioritize them or triage them according to how likely/feasible is it for a regular user to write similar code "organically". In this provided pure synthetic example, it involves nesting concat!
10000 times and the example was synthetically generated. This is not a pattern that typical users will likely run into. On the other hand, if the compiler crashes from resource exhaustion e.g. from just 1000 macro calls in a row, then we would consider that a higher priority issue and something users are more likely to write "organically".
IMO there are several by-design security risks for developers using rust right now. When you build software with rust, you're unknowingly accepting these security risks. The stance of rust security team elegantly avoids these risks by stating they are out of scope because all code is trusted.
I'm currently trying to document these security risks, so they can be explicitly accepted by developers using rust, and maybe nudge the rust security team towards implementing more security controls and fail-safes so rust follows a more defense-in-depth approach.
I think this is explicitly a non-goal for rustc
and we assume "all code is trusted" with regards to the input as you stated. If you wish to discuss security concerns, please file a separate dedicated issue or discuss with @/rust-lang/security.
I have documented how rust users can be exploited by compiling untrusted code with rustc (expected from many other languages, but could be improved with rust), by generating documentation for untrusted code with rustdoc (unexpected, should not happen imo), and of course by running the compiled untrusted code (expected).
If you are compiling untrusted code with rustc
, I think you have bigger security problems than rustc
possibly crashing, i.e. doing that in the first place.
EDIT: to add, the build might be sandboxed, but that concern is delegated to you.
But getting all your data stolen by simply formatting code with rustfmt would be both an unexpected finding and the cherry on top, so please let me know if you think this issue is exploitable ;)
This is simply not a threat model that we consider, AFAIK.
@bf A stack overflow does not, itself, constitute an exploit, as the term is commonly defined in security research[^0].
If you are familiar with security research involving languages that are compiled to machine code, you must know this? I would hope you would have read the error message and recognized that this hit a signal handler that responds to the quite-intentional page fault caused by hitting the stack protector[^1]. I would hope that if you are familiar enough to be able to confidently make claims about security concerns and exploits, it would not need additional explanation... but perhaps it is missing something in the diagnostic? I am happy to amend it, if so, but it would have to be a small addition, as it already uses a lot of vertical space and I don't think we can fully explain "what is a page fault, anyways?" within that.
Otherwise, I am not sure from where you have derived the idea that, by putting in an amount of code that induces resource exhaustion, you have reached an exploit. As a batch program, rustc is not even expected to be particularly resilient to resource exhaustion, unlike e.g. a web server, where such might be a reasonable expectation? We can make rustc resilient more resilient to inputs, but that might compromise other desirable qualities like speed of compilation, or simply divert work from more important things, like making it easier to write safe code with rustc (so that other programs that rustc compiles are more secure by design). Eventually, all programs will run out of memory if they are given a sufficiently ridiculous task, and the errors are rarely pretty.
All these considerations happen in addition to the detail that jieyouxu already described regarding the trustedness of certain inputs.
[^0]: It is possible that the stack overflow could be argued to be a software flaw or even vulnerability, but an exploit is the usage of that flaw or vulnerability to subvert a system. [^1]: Pages that are deliberately mapped in such a way that access to them, especially write access, will cause a fault, that usually gets translated to SIGSEGV on POSIX systems.
If you are familiar with security research involving languages that are compiled to machine code, you must know this?
Unfortunately I'm not good with machine code & exploiting overflows, which is why I asked. Thanks for confirming that the SIGSEGV is not exploitable @workingjubilee.
This is simply not a threat model that we consider, AFAIK.
I understand this, and I think it is an artificial blind spot in rust security posture.
I have gathered my thoughts on rust security at https://github.com/bf/rust-security-problems and will create new reports for the most glaring issues. Then the issues and your decision will be documented.
cc @rust-lang/security just in case you're interested. I can't tell if OP was trying to address you.
Triage: let's keep this issue focused on the resource exhaustion stack overflow from the code sample itself and open separate issues for the security concerns.
You might be interested in reading the discussion in https://github.com/rust-lang/rfcs/issues/1515
Then the unfamiliarity is understandable. I am happy to try to answer some questions you may have regarding such.
A stack overflow is a segfault. Almost all such segfaults are very hypothetically exploitable: you have to find a way to bypass the protection. However, as mentioned, you are running headfirst into the exact wall that is designed to prevent things from getting worse, and you are doing the exact thing that would normally cause you to run into that wall. It's rather like intentionally running a command that can reformat your hard drive, and then not even reporting that your hard drive was formatted, but that a window popped up to ask for your password before you destroyed your access to your computer's data. Yes, that little popup was supposed to be there.
To say "I found an exploit" implies something more like "I found a way to run the command that reformats my hard drive without hitting the password check". That would transgress a security boundary. Here, you are starting on the other side of the airtight hatchway, so there are quite a lot of interesting things you can do by running a program that can read and write to the filesystem.
Code
Use javascript
x=10000; out="compile_error!(" + "concat!(".repeat(x) + '"A"' + ")".repeat(x); + ");"
to create rust code.Full code in evil3.rs.txt
Meta
rustc --version --verbose
:Error output