Some ways to test if a program securely runs other programs

June 30, 2011

Suppose that you have a program that can run other programs, and you want to find out if it securely runs the other programs. In an ideal world, the program's documentation would tell you, and you could trust it. Sadly we do not live in an ideal world.

First you need a test environment where you can control what external program your program runs and force it to actually run the program. In many cases (such as testing daemons, web servers, MTAs, and so on), the easiest test environment is a virtual machine. Next you need a program that logs its arguments in some appropriate place.

Let's say that we're testing a daemon with a configuration option called 'av_scanner' and that our program to report arguments is called argreporter.

Our first test is whether straight shell metacharacters have any effect:

av_scanner = /opt/argreporter 'test' >/tmp/canary

After you get the daemon to run your configured 'AV scanner', check argreporter's logs; if it is run securely, it should have seen exactly these two arguments. If it was run through the shell, it will have seen one argument that won't have quotes (and /tmp/canary will exist). Variants of this are possible; for example, some programs will helpfully run the av_scanner command line through the shell if they see shell metacharacters.

If your program fails this check, you can stop now. Otherwise, though, we still need to test the substitutions that your program does. For this, we need to find some substitution that introduces a space; the best one is a variable substitution, because those are usually the simplest. Suppose that we have a $recipients variable that has a space separated list of destinations; then:

av_scanner = /opt/argreporter $recipients

The logs should show that argreporter was called with one argument and that the argument had spaces in it. If it was called with several arguments and each argument was a single destination, your program makes substitutions before breaking the command line up into arguments and you've just seen why this is somewhere between annoying and dangerous.

(Another important test is what happens with empty or blank substitutions. You want these to result in an argument of '' instead of the argument just disappearing.)


Comments on this page:

From 174.46.233.130 at 2011-07-20 00:07:27:

Since you're indirectly referencing Exim, I'll point out that Exim explicitly does not use the shell unless directed to do so, but does do some tokenisation (before substitution) itself.

spec.txt: 29.3 How the command is run for pipe transports, but also applicable to parsing of the cmdline: av_scanner option

-Phil P

Written on 30 June 2011.
« Please have symmetric option negotiations in your protocols
Dear Googlebot: SMTP is not HTTP »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Jun 30 23:00:47 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.