Issue #8468 has been updated by Student (Nathan Zook).


headius (Charles Nutter) wrote:
> $SAFE is not a good security option for at least a few reasons:
> 
> * It requires maintaining checks for both tainting and safe levels in nearly *every* piece of C code attached to Ruby, including extensions. This is both a maintenance and performance nightmare.

Part of the issue here is the balance of pain.  You have the pain of the core team verses the pain of platform providers verses the pain of end developers verse the pain of the organizations that use the code in question.  We now have a Rails server botnet thanks to $SAFE = 0.  How much pain is that going to be in the world?

Do you have specifics about the performance costs?

> 
> * It provides a very coarse-grained security, where many secured features are only secured at levels that prevent most applications from working at all (due to other secured features being needed.

I have a real hard time with your vagueness here.  All SAFE=1 does is prevent tainted data from being executed, for a broad definition of executed.  Unless you are doing something like tryruby.org, there is no reason at all that this should ever be a problem.  If you are, then of course, you are going to need a more robust security model than SAFE=1 can provide.

> * It is blacklisting, which is almost impossible to do without leaving gaps. EVery new API needs to enlist in the blacklisting, every change needs to be aware of it, and if you don't choose the right safe level or one piece of code isn't aware of it, you've got a hole.

I agree that blacklisting is problematic in general.  I don't agree that it is nearly so dire at this point as you say.  As I mentioned, SAFE=1 is solely intended to prevent tainted strings from being executed, in the broad meaning of the term.  Defined in this way, it is pretty straight forward to reason about.  If you aren't mucking around with some new form of I/O, set SAFE=1, don't be stupid about untainting, and be happy.  If you are, well, then you **** sure better dot your i's & cross your t's.  Security is just one of the things on that list.

I don't know how the implementation is done, but it seems to me that internally, it is all about keeping up with the taint bit, and that it is only at the edges (I/O & eval) that $SAFE=1 comes into play.


> The security model provided on the JVM or on operating systems with access control lists are both better options. If you run with security on, everything is forbidden; you must explicitly turn *on* the permissions you want and whitelist those capabilities. Those permissions are fine-grained, allowing you to disable only code evaluation or filesystem access or dynamic library loading, rather than having to choose from four pre-determined blacklists.

NOW we have an alternative suggestion.  But I'm not thrilled with what you are suggesting.  Perl's safe mode is very close to our $SAFE=1, and they make use of it.  We don't.  Now you suggest requiring end developers, who can't be bothered to worry about which of 5 options to use, to make a dozen or so correct fine-grained choices on things they might not understand at all?

In real life, this looks something like the following:  Write code.  See code fail.  See the security mechanism.  Disable the security mechanism.  Repeat.  This mentality regarding SAFE is already here.  Given the response to bug January, I don't expect things to get better by making devs work more to achieve the result.

> Regarding the Rails exploit...SAFE=1 may or may not have helped, but the real problem was allowing arbitrary code to be embedded and executed from a *data* format in the first place.

I would say that this is *exactly* what SAFE=1 is supposed to prevent.  Those strings are tainted, and under SAFE=1, you can't eval tainted strings.

The fact that Psyche calls []= on objects whenever the user-supplied data tells it to is a problem in its own right, but even that would not have been a problem if SAFE=1.

The symbol exploit probably would still be there.  My Symbol[] proposal is designed to allow an easy fix for that one.

> Regarding Perl... even the Perl folks say tainting is not intended to be used as a general security mechanism...it is *at best* a way to audit code for egregious security flaws.

> Regarding why the Ruby community has not moved away from SAFE... they actually have. For most online servers that are used to run user code (tryruby.org, various online ruby tutorials and schools, etc) they are using *JRuby* with JVM security policies rather than the broken and troublesome SAFE support in MRI. It's time for MRI to move away from SAFE as its sole security model too.

Unlike the originator of this thread, you at least appear to be proposing that we move TO something.  Certainly having fine-grained control available is desirable.  I will argue, however, that adoption goes much better if you have one or two big red buttons to push instead of a control board full of sliders.  I will look into the JVM security model & see what I think.




----------------------------------------
Feature #8468: Remove $SAFE
https://bugs.ruby-lang.org/issues/8468#change-39638

Author: shugo (Shugo Maeda)
Status: Feedback
Priority: Normal
Assignee: shugo (Shugo Maeda)
Category: core
Target version: current: 2.1.0


Yesterday, at GitHub Tokyo drinkup (thanks, GitHub!), Matz agreed to remove the $SAFE == 4 feature from Ruby 2.1.
Shibata-san, a developer of tDiary, which is the only application using $SAFE == 4, also agreed to remove it, so today is a good day to say goodbye to $SAFE (at least level 4).

Furthermore, I'm wondering whether $SAFE should be removed entirely, or not.
Is there anyone using $SAFE?


-- 
http://bugs.ruby-lang.org/