Working Remotely? Thinking about it?

Are you a member of a geographically dispersed team? Are you thinking of working remotely, or hiring remote developers? Wide Teams is my new blog and podcast for distributed teams. Check it out for getting started guides, tips and best practices, news, interviews, screencasts, and more all about working remotely and collaborating with wide-spread teams.

Safely executing commands with user data

2009 October 19
by avdi

Do you ever need to call out to a shell command with some user-supplied arguments?

category = 'riddles'
fortune = `fortune #{category}`

Q:      What's the difference between a Mac and an Etch-a-Sketch?
A:      You don't have to shake the Mac to clear the screen.

It all seems fine and good until some wise-ass comes along and messes things up for everyone.

category = '; rm -rf *'
fortune = `fortune #{category}`

It doesn’t have to be this way though. You can force process arguments to be interpreted strictly as strings instead of being subject to shell evaluation. You just have to use the multi-argument form of methods which start subprocesses. This means that backquotes are out. We can use #system() though…

filename = '; rm -rf *'
system('test', '-e', filename) # => false

That doesn’t help us with our original example, though. We need the output. Open3 will do the trick:

require 'open3'
category = '; rm -rf *'
output = ""
fortune = Open3.popen3('fortune', category) do |stdin, stdout, stderr|
  output += stdout.read
  output += stderr.read
end
puts output

No fortunes found

This technique is not a sure-fire defence against malicious data. It will be of little help if the command you are invoking can start a subshell, so be especially careful when calling out to shells or to other scripting language interpreters. But for simple commands it can provide a layer of protection.

Bookmark and Share
Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

Related posts:

  1. Greenletters: Painless automation and testing for command-line applications
  2. Ruby Subprocesses Part 3
  3. Utility Belt
  4. Everything You Love about Java is Everything I Love About Good Design
blog comments powered by Disqus