sabkat has asked for the wisdom of the Perl Monks concerning the following question:

I have code that calls another perl script like this:

system "inc_seqs -p " . $project->name . ($force?" -f":"");

I get this error:

Insecure dependency in system while running setuid at ../../bin/magpie_add_seqs line 84.

Line 84 is the snippet above.

My question is this: If there is a taint problem in "inc_seqs" which file would have the taint error, my spippet or "inc_seqs"?

I'm trying to track down this taint error. The @ENV. @INC and all the vars are cleansed, I've checked. I think the trouble is the script "inc_seqs", but I'm not sure.

Any help would be apreciated!

Replies are listed 'Best First'.
Re: cgi taint trouble
by abatkin (Sexton) on Feb 06, 2003 at 02:12 UTC
    I would suggest chapter 23 (Security) from the Camel book (Programming Perl 3rd ed).
    The first thing you can do, as long as you don't need anything from the shell (i.e. globbing), is to use system in a list context. Something like:
    @args = qw/-p $project->name/; push @args, '-f' if $force; system "inc_seqs", @args;
    This prevents potentially bad metacharacters from being interpreted by the shell (which system would use otherwise). In addition, to help out with taint checking, the following sub is suggested to test for tainted variables:
    sub is_tainted { my $arg = shift; my $nada = substr( $arg, 0, 0 ); # zero-length local $@; # preserve caller's version eval { eval "# $nada" }; return length($@) != 0; }
    Good luck!
Re: cgi taint trouble
by cees (Curate) on Feb 06, 2003 at 02:31 UTC

    It looks like the 'system' call you are making is using a tainted variable. So it is either going to be $project->name or $force. Have you untainted them?

    I am guessing that it is probably the $force variable, which looks from the name like it probably came from a command line switch. Even though you aren't using the value of $force in the system call, any expression that uses a tainted value will itself be tainted. From the perlsec docs:

    The value of an expression containing tainted data will itself be tainted, even if it is logically impossible for the tainted data to affect the value.
    Also, I would rewrite the system call to something like this:
    my @params = ('-p', $project->name); push @params, '-p' if $force; system 'inc_seqs', @params;

    If you pass a string to system, it will use a shell to parse the parameter list and execute the program. If you pass a list (or array) of switches and parameters, you skip the need for the shell, and the program is executed directly, which saves the chance of any nasty shell escapes from happening.

    Read the perlsec manual and it will explain how to do the actual untainting of the variables.