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

Invoking cargo completions in malicious project may lead to RCE #3740

Open
bjorn3 opened this issue Mar 24, 2024 · 2 comments
Open

Invoking cargo completions in malicious project may lead to RCE #3740

bjorn3 opened this issue Mar 24, 2024 · 2 comments

Comments

@bjorn3
Copy link
Member

bjorn3 commented Mar 24, 2024

A simple repro would be a project dir with the following contents:

rust-toolchain.toml:

[toolchain]
path = "/path/to/project"

bin/cargo (executable bit set):

#!/usr/bin/env bash
echo "Malicious code executed" > oops.txt

And that's it. If you now try to do shell completion in bash for "cargo check --bin " (trailing space important to avoid getting "--bin" and "--bins" as completions), a file called oops.txt will be created with "Malicious code executed" as content. (This needs the cargo bash completion to be enabled)

This RCE works because the cargo completion invokes cargo to get the list of bin targets. When using rustup, rustup will try to invoke the cargo of the active toolchain, which in this case is the project directory itself thanks to the rust-toolchain.toml file and as such bin/cargo in the project directory is invoked.

While it would be true that actually running the cargo command would allow running arbitrary code already, this is a lot more widely known and less surprising. I don't expect completions to have any side-effects like running malicious code in the POC.

This issue is mostly disclosed already in rust-lang/cargo#6645 (comment) as I didn't realize that the current state of the cargo completions already allow this. No POC has been posted there though.

For reference oh-my-zsh used to have a similar RCE opportunity by running "rustup run completions zsh cargo" whenever opening a new shell. This would run "cargo completions zsh" for the active toolchain of the directory in which the shell was opened. After I reported this, it was changed to use the default toolchain instead in ohmyzsh/ohmyzsh@a01cf85

The POC is shared with the security team made use of path = "." which no longer works as of #3340. According to #3461 it should be possible to use /proc/self/cwd as workaround, but I couldn't get this to work on my machine. For a targeted attack it is likely still possible to guess the location where the victim will clone the malicious project.

@rami3l rami3l added this to the On Deck milestone Mar 25, 2024
@rbtcollins
Copy link
Contributor

Since commands are consistent everywhere, one fix would be to change completions to also always use the default toolchain.

@bjorn3
Copy link
Member Author

bjorn3 commented Apr 8, 2024

That would cause issues when a project uses nightly cargo features but the default toolchain is stable. It is probably the safest option though. Oh-my-zsh does the same when for loading the completion script itself.

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

No branches or pull requests

3 participants