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

Hi, I've been working on a CGI script which is essentially a web interface for a perl script on the machine that does all of the heavy lifting. After getting things working on my own machine, I moved it over to a shared machine so that other people could use it. However, it isn't executing on this new machine. At first, I was getting errors about insecure dependencies and tainting issues, but even after seemingly dealing with those issues the perl script fails to execute after being called. For reference, here's the code on the old machine:

my $detail = ""; $detail = join("", $detail, "perl LGE.pl " ); $detail = join("", $detail, "--target $target ") if defined $targe +t; $detail = join("", $detail, "--port $portnum ") if defined $portnu +m; $detail = join("", $detail, "--interval $interval ") if defined $i +nterval; $detail = join("", $detail, "--protocol $protocol ") if defined $p +rotocol; $detail = join("", $detail, "--source $prmlist ") if defined $prml +ist; $detail = join("", $detail, "--start"); my $command = qx($detail);

And after dealing with the insecure dependency/ tainting issues:

my $detail = ""; $detail = join("", $detail, "/usr/bin/perl LGE.pl " ); $detail = join("", $detail, "--target $target ") if defined $targe +t; $detail = join("", $detail, "--port $portnum ") if defined $portnu +m; $detail = join("", $detail, "--interval $interval ") if defined $i +nterval; $detail = join("", $detail, "--protocol $protocol ") if defined $p +rotocol; $detail = join("", $detail, "--source $prmlist ") if defined $prml +ist; $detail = join("", $detail, "--start"); $ENV{'PATH'} = '/bin:/usr/bin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; untaint($detail); my $command = qx($detail);

It seems like the only real difference is the machine that the code is running on. I went back and ran the new CGI on the old machine and it works. Is it possible that something is preventing my CGI from properly interacting with my script, and if so, any guesses to what it might be?

Thanks,

Trenin

Replies are listed 'Best First'.
Re: System Configuration Blocking CGI System Calls? ( shell escapes)
by Anonymous Monk on Jan 05, 2015 at 22:48 UTC

    untaint($detail);

    Where did you learn about taint? That is the wrong way to untaint if you're going to use the shell (qx), so you should avoid the shel with system

    The easy way

    sub GetLGE { use Capture::Tiny qw/ capture /; local %ENV; delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; $ENV{'PATH'} = '/bin:/usr/bin'; my @args = ( $^X, 'LGE.cgi' ); push @args, ...; untaint($_) for @args; my($stdout, $stderr, $exit) = capture { system { $args[0] } @args; };; if( $exit ){ die "got the exit( $exit ) and stderr: $stderr\n "; } return $stdout; }

    The other way is String::ShellQuote

Re: System Configuration Blocking CGI System Calls?
by Anonymous Monk on Jan 05, 2015 at 23:42 UTC

    Sorry to be so direct but do not do it that way - if any one of those strings is coming from the web then you have a giant security hole: What if one of those strings contains something like "; rm -rf /whatever" or "; cat /etc/passwd"? The tainting mechanism is trying to tell you just that, so the point is not to simply blindly untaint stuff, you're supposed to check it for security issues (like removing shell metacharacters) - see perlsec for more on this topic.

    The other anon already showed you Capture::Tiny, just to point out another one: capturex from IPC::System::Simple will never invoke the shell, avoiding the above issue of shell metacharacters. It also has the nice feature of more helpful error messages, which sounds like what you need at the moment.

    any guesses to what it might be?

    I prefer seeing the actual error messages over guessing :-)

A reply falls below the community's threshold of quality. You may see it by logging in.