tags:

views:

203

answers:

2

Ruby's safe mode disallows the use of tainted data by potentially dangerous operations. It varies in levels, 0 being disabled, and then 1-4 for levels of security. What vulnerabilities are possible when safe mode is enabled? Do you know of any CVE numbers issued to a ruby program when safe mode is enabled? What CWE Violations (or cwe families) are possible with safe mode enabled?

+5  A: 

Since $SAFE >= 1 only protects you form using tainted input in unsafe operations, such as eval and so on, any vulnerability in a safe Ruby method would still be a problem. For instance CVE-2009-4124 only requires that you use the functions ljust/center/rjust on an input, and at least my version of ruby 1.8.7 considers those functions safe. Here is a Ruby snippet that uses $SAFE = 4, and would definitely be vulnerable to the above problem:

$SAFE = 4; ARGV[0].ljust(ARGV[1].to_i)

In general, most Ruby vulnerabilities could still be targeted even if the Ruby script runs in safe mode.

Also, with $SAFE = 1, you can untaint variables, and thus your application is vulnerable as soon as you untaint and subsequently use that variable in a non-safe way, the application is still vulnerable.

grddev
+1 great point, any function can be a sink if it suffers from memory corruption in the language or in a library.
Rook
+4  A: 

All application-level vulnerabilities are completely unaffected by the $SAFE level. Injection attacks that don't pass through an "unsafe operation" like cross-site scripting and SQL injection for example. This includes, more or less, every vulnerability class for web applications, except perhaps local and remote file inclusion. See the OWASP Top 10, $SAFE doesn't help with many of these.

The $SAFE level does protect you somewhat against system-level vulnerabilities though. If an attacker is able to write Ruby code into a file in /tmp, they wouldn't then be able to trick your program into loading that code if $SAFE >= 2.

And this of course doesn't include any vulnerabilities with Ruby itself. These are much more serious, and can bypass $SAFE entirely.

Or plain old buffer overflows, integer overflows, etc in the Ruby interpreter itself that have nothing to do with $SAFE.

Rails has a history vulnerabilities that occur whether $SAFE is enabled or not. This is complicated by the fact that user input is stored in Rails applications, and malicious data can pop back up at a later time.

Vulnerability reports in Ruby applications other than Rails and MRI are hard to come by.

Another big problem with $SAFE is there is no real list (that I know of) that outlines exactly what $SAFE does and doesn't protect. About the only thing you can do is search for *ruby_safe_level* in eval.c (this is an older eval.c from 1.8.4). The comments provide this description, but it's pretty vague.

/* safe-level:
   0 - strings from streams/environment/ARGV are tainted (default)
   1 - no dangerous operation by tainted value
   2 - process/file operations prohibited
   3 - all generated objects are tainted
   4 - no global (non-tainted) variable modification/no direct output
*/

I guess what I'm trying to say is that $SAFE is all about system security. It does an OK job, but there's no real way to know exactly what is and is not protected. It shouldn't be your only line of defense, it's more of a safety net so nothing slips through to an "unsafe operation." On the other hand, it has nothing to do with application security, and won't save your data or users from being compromised. And on top of that, MRI has a history of vulnerabilities that bypass $SAFE entirely.

AboutRuby
Wait i thought PHP was the only one that was affected by remote file include. Doesn't ruby's include really accept a url? Do you have any links in regards to ruby LFI/RFI attacks?
Rook
Ruby isn't really vulnerable to RFI, as far as I know. However, if you include the open-uri library, any call to open can potentially open a URL. This won't affect either require or load (used to load Ruby code), but it could potentially effect anything else that opens a file. Though the conditions this can happen under are limited, since Kernel#open has to be used, instead of File#open (the usual idiom for opening files).It's just as vulnerable to LFI is someone is foolish enough to put user input in a load or require statement. $SAFE should catch this though.
AboutRuby
Kernel#open has other vulnerabilities that aren't immediately obvious as well. For instance, if the first character is a pipe, it will open a subprocess and use the output of that as its file stream.
AboutRuby