From: Bill Kelly Date: 2009-01-13T08:49:03+09:00 Subject: Re: Binding.of_caller examples don't work. From: "Charles Oliver Nutter" > > Bill Kelly wrote: >> If we're calling untrusted code and giving it full execution privileges, then >> I think Binding.of_caller is the least of our worries. The untrusted code >> could as easily `rm -rf ~` or innumerable other evil things. >> >> Untrusted code needs to be sandboxed. > > Sandboxing is made nearly impossible if calls in your own chain can escalate privileges by executing code from your binding. Since you mention below JRuby doesn't support $SAFE, then I'm at a loss as to which sandboxing mechanism you refer. (Does JRuby offer an alternative sandboxing approach?) It seems to me there's trusted code, and untrusted code. We allow trusted code to do all sorts of potentially dangerous things, including reopening and redefining any method in any class, etc. etc. So again, if we're talking about trusted code, I'm hard pressed to see the validity of holding Binding.of_caller up as an exemplar of something somehow more dangerous than the myriad privileges already granted to trusted code in ruby. Conversely, if we're talking about untrusted code, Binding.of_caller seems a relatively unremarkable addition to an already existing great number of avenues by which untrusted code can affect the system unless (somehow) sandboxed. If no such sandboxing mechanism exists, then why pick on Binding.of_caller in particular? > This is the primary reason why prototype continuation support for the JVM probably will never be shipped...the ability to > implicitly access things elsewhere in the call stack has all sorts of really nasty security issues, even in a pretty secure > environment like the JVM. > >> Seems we could either make Binding.of_caller not work at all if $SAFE >> is >= 3 ... or preferably, if it's possible for the interpreter to determine >> whether the caller's binding would have a lower $SAFE level than the >> current binding, then only raise a SecurityException in that case. >> >> Would this address your security concerns? > > No, because JRuby doesn't support $SAFE. It's a blunt instrument that I don't think anyone has ever audited for actual safety. So > as a result, anyone believing $SAFE is actually safe is probably introducing even more risk into their apps. > > Also, $SAFE is a global thing, and you can't localize it to a given binding, so that wouldn't work anyway. It's thread local. And it apparently somehow does get localized to a given binding (?) because ruby remembers the $SAFE level at which a lexical closure was compiled (or at least, a proc.) For example, if a thread is at $SAFE=4, and calls a proc which was compiled at $SAFE=0, then the proc executes at $SAFE=0. I do share your concerns about $SAFE never having been formally audited for security, and I'd agree it would be foolish to assume there don't exist some undiscovered holes in the system. (On the other hand, in practical terms, we live with as yet undiscovered security holes in windows, linux, IIS, apache, etc. every day too.) That said, it appears $SAFE=4 was designed with the _intent_ to provide a secure sandbox. And it seems to me the $SAFE mechanism could as easily disallow inappropriate uses of Binding.of_caller, just as it currently disallows the reopening of classes and modules, etc. > Honestly, if you want a binding, pass one in. Been there, done that. As Matz pointed out with respect to other dangerous features: "open class" is so strong (often too strong), we can break things easily. In other word, Ruby trust you to give you sharp knives, where Python don’t. From the Python point of view, it’s wrong, I guess. Again, I don't see why Binding.of_caller is particularly sharper than many other knives in ruby. (If I try to imagine writing malicious code I know will be executed with full privileges, Binding.of_caller isn't the first tool that comes to mind when I contemplate all the nefarious possibilities.) Regards, Bill