Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What vulnerabilities are possible in ruby with $SAFE >= 1?

Tags:

security

ruby

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?

like image 317
rook Avatar asked Aug 05 '10 17:08

rook


2 Answers

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.

  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-3657
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-3655
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3694
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-2337

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

  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2489
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-4124
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-2726
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-2376

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.

  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-4214
  • http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3009

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.

like image 62
AboutRuby Avatar answered Oct 31 '22 09:10

AboutRuby


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.

like image 30
grddev Avatar answered Oct 31 '22 11:10

grddev