postmodern / chruby

Changes the current Ruby
MIT License
2.85k stars 190 forks source link

should ruby-specific $PATH be put at the end of existing $PATH instead of beginning? #428

Closed jrochkind closed 1 year ago

jrochkind commented 4 years ago

My $PATH without chruby.sh looks like:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin

With chruby.sh in my .bash_profile, it looks like:

/Users/jrochkind/.gem/ruby/2.4.2/bin:/opt/rubies/ruby-2.4.2/lib/ruby/gems/2.4.0/bin:/opt/rubies/ruby-2.4.2/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin

That is, the ruby-specific directories -- including gem bins -- have been put at the beginning of $PATH.

If a malicious or clumsy installed gem provided an executable called make, cd, ssh, etc, when typing such in a shell, the gem-provided executable with the same name as the standard utility I meant to call would be found first, and executed.

Is this a security issue? Would it be preferable to add ruby-specific PATH -- or at least specifically any directories that can include third-party gem-provided executables -- at the END of $PATH instead of the beginning?

svoop commented 2 years ago

I'd vote in favor of this change for the given security reasons. However, there's another reason:

When using binstubs and you don't want to type type the bin/ prefix, there are pretty common patterns such as:

I've tried both and no matter how I set up things, the auto.sh from chruby always puts it's ~/.gem-bindirs first. That's particularly uncool when you use the spring gem: It patches the binstub ./bin/rails which is never executed because there's the .gem/ruby/x.x.x/bin/rails script coming first in the path.

Appending rather than prepending these paths solves the problem.

@postmodern What do you think? Would you accept such a PR?

eregon commented 2 years ago

Appending to PATH won't work if there are gem binaries or ruby already in PATH, e.g., from the system Ruby.

svoop commented 2 years ago

@eregon That's true for binaries (ruby, irb etc), they have to be prepended to the PATH. But we're referring to the scripts/binaries provided by gems.

Here's what chruby prepends to my PATH:

/Users/me/.gem/ruby/3.1.0/bin:/Users/me/.rubies/ruby-3.1.0/lib/ruby/gems/2.7.0/bin:/Users/me/.rubies/ruby-3.1.0/bin

Let's break it down:

eregon commented 2 years ago

What if there are system gems installed, e.g. /usr/bin/rspec? That would pick the wrong executable.

svoop commented 2 years ago

@eregon

Fair point!

I tend to forget about system rubies (macOS was supposed to unbundle it at some point).

This means the safety concerns cannot be addressed unless chruby is overhauled big times adding a way for the user to select the append/prepend behavior... maybe not compatible with the no-bloat promise of chruby.

As for the binstubs: Would it be an acceptable extension to have chruby prepend .git/trusted/../../bin as first entry to the PATH?

The README could then explain its purpose: To priorize project binstubs, do mkdir .git/trusted in the project root. (Or if you do this often, add a git alias git trust which creates this directory.)

(Plan B is something like direnv with "layout ruby" instead of chruby, but I don't really like the idea of dumping chruby, it's worked too well so far.)

jrochkind commented 2 years ago

I'm not familiar with this .git/trusted, and am not succesfully finding the context googling. Can you link to an explanation of this?

svoop commented 2 years ago

Since the name of the directory doesn't matter, there are different ones out there such as the thoughtbots using .git/safe. In order to make the relation between the git alias git trust-bin and the directory more apparent, I personally prefer .git/trusted.

postmodern commented 1 year ago

Closing this since the rubys bin/ and rubygems bin/ directories must be prepended to the path in order to override system ruby, rake, irb, or any other system gems.

As for binstubs, it may be possible to either add the binstubs directory or re-alias the gem executables to use bundle exec.