Command Injection in Rails

Command Injection is a type of injection where attackers gains access to your system through your application. It occurs when a system command includes user manipulatable values.

Here are the common command lines which we generally use in rails application:

  • `….`
  • system()
  • %x[….]
  • exec()

Now, this is what command injection looks like:


path = "#{Rails.root}/public/#{params[:name]}"

`mkdir -p #{path}`

`ls #{params[:file]}`

Here, as the params data is provided by user, so it can be used by attacker to manipulate our system command and execute it.

In the above case, the attacker can just pass params[:file] value as  ; cat ./config/database.yml  and thats it. Just by doing this they have gained access to view your database credentials which is obviously sensitive.

So, how to prevent this from happening?

In order to prevent it from attack like command injection, we need to break our command into separate strings like this:

 

path = "#{Rails.root}/public/#{params[:name]}"

system("mkdir", "-p", path)

system("ls", "params[:file]")

Hope you liked it, for more such information stay tuned 🙂

Advertisements

What is this Rack?

We as developers use frameworks like Rails, and while using it everything seems like magic to us because of abstraction. But have you ever thought of how the internal Request/Response cycle works in these frameworks Or who is the one driving it internally ?

 

HOW?

 

So, to solve everyone curiosity, RACK is the one which is responsible for handling all these things.

But what is this RACK??

What is that?

 

Rack is the middleware which helps application server to run your rails app. You can think of it as a common language that both your app server and rails application understands. So, our app server interacts to our rails application using rack(translator).

 

RACK INTERFACE

Rack defines a simple interface and it must have these three properties:

  1. It must respond to Call method
  2. Call method takes a single argument, termed as env/environment. This env contains all the data about the request
  3. Call method returns an array of three elements which is [status, headers, body] of the response

 

Lets understand this by writing a simple rack complaint application, which returns the text “Hi, I am RACK” 🙂

 
require 'rack' 
require 'thin' 

class RackApp 
 def call(env) 
  [ 200, { "Content-Type" => "text/plain" }, ["Hi, I am Rack"] ] 
 end 
end 

Rack::Handler::Thin.run RackApp.new 

In the above example we can see that RackApp is a class which has one instance method termed as
call which takes env as a argument and returns an array containing three elements:

  • Status Code: 200(HTTP “OK” status)
  • Header: Content-Type(text/plain)
  • Body: [“Hi, I am Rack”]

Here one thing to note down is that Body of the response must respond to each, thats why normal string is enclosed in an array and then returned. But in case of some type of IO object this enclosing inside array is not required.

 

Hope you liked it. In the next blog we will be covering little complex designing using Rack interface. So for more such information stay tuned …. 🙂

 

Performance Tip In Ruby

Today performance is what that comes first, both from the end-user perspective and from developers point of view. So in this blog, I’ll be covering some simple things which we developers should follow, in order to optimize performance of our ruby code.

Here are the some tips with there benchmarking result:

  • Always use string interpolation instead of string concatenation
  language = "ruby"
  Benchmark.bm do |x|
    x.report {p "testing string, "<< language}
    x.report {p "testing string, #{language}"}
  end

  [#<Benchmark::Tms:0x000000000b271388 @cstime=0.0, @real=6.565399962710217e-05, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>,
   #<Benchmark::Tms:0x000000000b270b40 @cstime=0.0, @real=4.6490000386256725e-05, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>]

From the above benchmarking, we can see that string concatenation operation is slower than the string    interpolation operation.

  • In ruby destructive operations are faster, we all know destructive operations are risk prone, as they modify the actual value, instead of modifying the copy. But if we have such use-cases where, we want to modify the actual object, than we should go for this destructive ones
  hash1 = {"color": "blue", height: 100}
  hash2 = {"width": 200}
  Benchmark.bm do |x|
    x.report {hash1.merge(hash2)}
    x.report {hash1.merge!(hash2)}
  end

  [#<Benchmark::Tms:0x000000000b090078 @cstime=0.0, @real=7.367998478002846e-06, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>,
   #<Benchmark::Tms:0x000000000b08f880 @cstime=0.0, @real=3.569999535102397e-06, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>]

As we can see from the above benchmarking, destructive operations are nearly two times faster than the normal operations.

  • Parallel Assignments are slower than the normal assignment
  Benchmark.bm do |x|
    x.report {var1,var2 = 1, 2}   #parallel assignment
    x.report {var1 = 1; var2 = 2} 
  end

  [#<Benchmark::Tms:0x000000000a2d59d8 @cstime=0.0, @real=8.679999154992402e-06, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>,
   #<Benchmark::Tms:0x000000000a2d5230 @cstime=0.0, @real=5.723002686863765e-06, @cutime=0.0, @label="", @stime=0.0, @total=0.0, @utime=0.0>]

Just look at the above benchmark output, it justifies that parallel assignments are slower.

  • Magic statement in Ruby:  frozen_string_literal

In ruby, we know that strings are mutable, what does that even mean?

In order to understand this, Let’s take an example:

  hash1 = {"width": 200}
  
  def get_width
    hash1["width"]
  end

In the above code, whenever get_width will be accessed, it will always allocate memory for the string “width”. so, in order to solve this, ruby introduced the concept of “freeze”, now calling the above code like this will solve the problem.

 
  def get_width
    hash2["width".freeze]
  end

But using freeze, everywhere with strings, will makes our code unclean and not DRY.
So, for this Ruby 2.3 introduced MAGIC COMMENT, termed as frozen_string_literal.

When we add this magic comment “frozen_string_literal” to any ruby file, all the strings within that file will be treated as immutable resulting in improving our code performance.

  # frozen_string_literal: true

  hash1 = {"width": 200}
  
  def get_width
    hash1["width"]
  end

For more information like this, stay tuned 🙂