Search code examples
rubysecurityshellsystemsanitization

Forming sanitary shell commands or system calls in Ruby


I'm building a daemon that will help me manage my server(s). Webmin works fine, as does just opening a shell to the server, but I'd prefer to be able to control server operations from a UI I design, and also expose some functionality to end users.

The daemon will pick up actions from a queue and execute them. However, since I'll be accepting input from users, I want to make sure they're not permitted to inject something dangerous into a privileged shell command.

Here's a fragment that exemplifies my problem:

def perform
  system "usermod -p #{@options['shadow']} #{@options['username']}"
end

A gist that explains more: https://gist.github.com/773292

I'm not positive if typical escaping and sanitizing of inputs is enough for this case, and being a designer, I don't have a ton of security-related experience. I know that this is something that should probably be obvious to me, but its not!

How can I ensure that the web application that will create and serialize the actions can't pass dangerous text into the privileged process that receives the actions?

Thanks for the help
arb


Solution

  • It doesn't look like you need a shell for what you're doing. See the documentation for system here: http://ruby-doc.org/core/classes/Kernel.html#M001441

    You should use the second form of system. Your example above would become:

    system 'usermod', '-p', @options['shadow'], @options['username']
    

    A nicer (IMO) way to write this is:

    system *%W(usermod -p #{@options['shadow']} #{@options['username']})
    

    The arguments this way are passed directly into the execve call, so you don't have to worry about sneaky shell tricks.