Feature #1800

rubygems can replace system executable files

Added by Kazuhiro NISHIYAMA almost 5 years ago. Updated almost 3 years ago.

[ruby-core:24472]
Status:Closed
Priority:Normal
Assignee:Eric Hodel
Category:lib
Target version:1.9.4

Description

=begin
Japanese blog http://wota.jp/ac/?date=20090604#p01 says,
gem has bin/ls and Gem::Specification#executables= ["ls"],
rubygem overwrites /usr/bin/ls without confirming.

I think this is potential security risk.
=end

History

#1 Updated by James Tucker almost 5 years ago

=begin
Doing sudo <installer> <package> is always a security risk.

Rubygems is neither the cause nor the vector for such an exploit.

The specific vector requires that the default install location be customised (e.g. Ubuntu / Debian)

Without a system registry, rubygems can at best warn that it will overwrite something, it cannot hold this notion of "system executable files", which is not clearly defined.
=end

#2 Updated by Run Paint Run Run over 4 years ago

=begin

Without a system registry, rubygems can at best warn that it will overwrite something, it cannot hold this > notion of "system executable files", which is not clearly defined.

It really should prompt before overwriting a file it didn't create, though. IOW, it doesn't need to know what a "system executable file" is, just what binaries it has installed for other gems.
=end

#3 Updated by Marc-Andre Lafortune over 4 years ago

  • Category set to lib
  • Assignee set to Eric Hodel

=begin

=end

#4 Updated by Yusuke Endoh about 4 years ago

=begin
Hi,

Eric Hodel has a duty to reply the ticket.

IMO, agreed with Run Paint. RubyGems should at least prompt.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#5 Updated by Marcus Rückert about 4 years ago

=begin
Eric and myself discussed this on irc and came to the conclusion that rubygems would need to track binaries installed by gems with path and their checksum.
When it updates a gem it would only overwrite the binary if the checksum still matches and the binary belongs to a former version of the same package.

the other option would be a seperate bin dir that you have to add to your $PATH.
=end

#6 Updated by Yusuke Endoh about 4 years ago

=begin
Hi,

2010/3/20 Marcus Ruckert redmine@ruby-lang.org:

Eric and myself discussed this on irc and came to the conclusion that rubygems would need to track binaries installed by gems with path and their checksum.
When it updates a gem it would only overwrite the binary if the checksum still matches and the binary belongs to a former version of the same package.

Thank you for replying! I think the feature is good.

Let us know what's the current status. Has it been implemented? Will
it be included in 1.9.2?

If it seems impossible, I'll change the target of this ticket to 1.9.x.

Thanks,

--
Yusuke ENDOH mame@tsg.ne.jp

=end

#7 Updated by Sakuro OZAWA about 4 years ago

=begin
Marcus, by this idea, what happens when a gem is being newly installed, not updated and there is a file that the gem is to overwrite?
I think we cannot track gem's wrappers' checksums since the sh-bang line may differ envs to envs in this case.

=end

#8 Updated by Yusuke Endoh about 4 years ago

  • Priority changed from Normal to High
  • Target version set to 1.9.2
  • ruby -v set to ruby 1.9.2dev

=begin
Hi,

I guess this feature request includes solution for security concern.
So I moved it to Bug tracker. Tell me if the move has a problem.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#9 Updated by Yusuke Endoh almost 4 years ago

  • Priority changed from High to Urgent

=begin
Hi, Eric

What do you think about this issue?
Are you planning to fix this before 1.9.2 release?

--
Yusuke Endoh mame@tsg.ne.jp
=end

#10 Updated by Yusuke Endoh almost 4 years ago

  • Status changed from Open to Assigned
  • Priority changed from Urgent to Normal
  • Target version changed from 1.9.2 to 2.0.0

=begin
Hi,

I realized more serious concern; "sudo gem install" executes
extconf.rb with root access, which enables code execution by
"an attacker".

I think this does not means any security issue, but means a
simple fact that rubygems assumes a user does not install
untrusted gems.

It is better to have an option to prompt before rewriting a
file or executing extconf.rb.
So I move this ticket to 1.9.x feature.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#11 Updated by Luis Lavena almost 4 years ago

=begin
On Sun, Jun 6, 2010 at 9:07 AM, Yusuke Endoh redmine@ruby-lang.org wrote:

I realized more serious concern; "sudo gem install" executes
extconf.rb with root access, which enables code execution by
"an attacker".

I think this does not means any security issue, but means a
simple fact that rubygems assumes a user does not install
untrusted gems.

It is better to have an option to prompt before rewriting a
file or executing extconf.rb.

Please note that any gem update that needs to replace a stub script
(rake, capistrano, etc) will prompt, so sudo gem update will be
pretty annoying.

--
Luis Lavena
AREA 17
-
Perfection in design is achieved not when there is nothing more to add,
but rather when there is nothing more to take away.
Antoine de Saint-Exupéry

=end

#12 Updated by Yusuke Endoh almost 4 years ago

=begin
Hi,

2010/6/6 Luis Lavena luislavena@gmail.com:

It is better to have an option to prompt before rewriting a
file or executing extconf.rb.

Please note that any gem update that needs to replace a stub script
(rake, capistrano, etc) will prompt, so sudo gem update will be
pretty annoying.

My opinion is an option to prompt, such as "gem update --prompt", for
conservative people. I'm not insisting to make the option default.

I also agree with the feature Marcus mentioned in .
It would be much better to prompt only when replacing a file that is
not under rubygems' management.

Anyway, this is just my opinion. I don't (can't) force Eric, though
I want Eric to express his own view or status.

--
Yusuke Endoh mame@tsg.ne.jp

=end

#13 Updated by Eric Hodel almost 4 years ago

=begin
Adding --prompt as a stopgap that defaults to off is acceptable to me. I don't know if I will have time to implement it until next week, though.
=end

#14 Updated by Vincent Batts almost 3 years ago

The --prompt option would leave vague, an important aspect of the implementation though, like gem update and gem uninstall.
It would seem then, let a state of omission should need to be recorded for the gems. So that those executables can be handled accordingly.

If a user were only --prompt'ed on the installation, but later the --prompt is omitted, and gem removes /usr/bin/ls, then it is no less better than clobbering the file in the first place. The user would effectively have to use --prompt on every install, update, pristine and uninstall.

For the same amount of work, to the user typing the flags, a more acceptable solution should be to create an alternate path, for executables to land ("/usr/ruby/bin") and have it in your shell's PATH (export PATH=/usr/ruby/bin:$PATH). Every time you gem install, just add the flag "-n DIR" or "--bindir DIR". This way, at best, a gem will only clobber other gems.

#15 Updated by Eric Hodel almost 3 years ago

  • Status changed from Assigned to Closed
  • Target version changed from 2.0.0 to 1.9.4

I've implemented this in the RubyGems repository, but it is too big a change to go into 1.9.3.

Rather than having users opt-in to checking if a RubyGems executable will overwrite something in their bin dir I'm using the following rules:

If --force was used, overwrite

If the executable exists and is for a different gem the user is consulted

If the executable exists and is in the default bin directory (for example, /usr/local/bin) the user is consulted

Otherwise, the executable is overwritten (gem reinstall or somebody was messing with the repository's bin directory)

With the fake gems of 1.9.x I think this meets all the criteria.

See:

https://github.com/rubygems/rubygems/commit/415c0ec4
https://github.com/rubygems/rubygems/commit/5298fffd

Also available in: Atom PDF