Monday, October 29, 2007

Calling command line tools from a web application

Occasionally, it's convenient (or practically necessary) to have a web application call a command line tool. If not done wisely, it can open up a huge security risk. For example, suppose we are using a simple command line tool that excutes a command like:

./simpletool $username

Now suppose someone creates a new user named "bill;rm -rf /" and passes it to a command line utility which executes:

./simpletool bill; rm -rf /

This will of course wipe everything out under /. Not good! It's not hard, if these interfaces have not been thought through, to find a string that does anything we want. Quotes, single quotes, and other special chars are easy to slip through and create major security holes. Buffer overflows could also be a problem... the command line can only accept a string of some finite length.

But while it's not ideal, it's not a huge security risk as long as there's some special safety considerations when handling user input. Here's a short list of security principles when using system calls:

After authentication and authorization is handled:

1. for all data, limit strings to a known set of characters
2. limit all strings to known sizes
3. limit all hashes of user input to known fields
4. avoid passing any data to the command line which isn't
programatically generated by you. If possible write user data to file, and pass your file names around. Otherwise, escape the data properly ... especially non-alpha-numeric chars like " ' ; \ ` $() which have meaning on the command line! Or better yet, just don't pass it on the command line.
5. escape all data that has special meaning (or could have special meaning) in the context in which it is used. For example, in a tab-delimited file, tab chars have special meaning.
6. limit file permissions to bare minimum ... nothing can be executable.
7. keep log of all interactions (leave the created files around for reference)

No comments: