Filed under: Ruby, System call, Security, featured
There are a few ways to execute system commands in Ruby: backticks, system, exec, %x, and Open3#popen3.
We will take a look at the their differences and briefly discuss security concerns of applying them.
When using backticks, the result is returned as string. Process status of method execution is stored in $?
%x() or %x is similar to using backticks.
When using system method, the result is true or false depending on whether the command is executed successfully.
exec replaces the current process by running the given external command. If you invoke exec in irb, then the irb process
will be replaced by the running external command. You will get the shell prompt back after exec finishes. If you invoke
exec in a ruby program, that program will stop execution (just like the irb process).
popen3 executes the command while opening stdin, stdout, and stderr and a thread to wait for the command execution.
stdout with successfully execution
stderr with unsuccessfully execution
There are a few variations of popen3 methods such as popen2 where a couple of streams are merged 2&>1, for example.
Much like SQL Injection, similar things can happen when using these method calls.
Consider a command like ls a;rm a. or even worse ls a;rm -rf *
We can address such concerns with another form of popen3(cmd, args). For the command above, it is
popen3('ls', 'a;rm -rf*'). The last part of the command is interpreted as the options for ls.