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

Greetings Perl Guardians

Encountering a problem I've never seen before while running -T

Insecure $ENV{ENV} while running with -T switch at /u/beta/coampsos/COSL/COAMPSOS/lib/COAMPSOS_rmon_monitor_tools.pm line 1496.

NOTE it says $ENV{ENV} and not $ENV{PATH} line 1496 is: open(CMD,"$cmd 2>&1 |") || return ($!);

From the following routine:

# Runs a command under -T captures output ###################################################################### +######## sub run_cmd_safely{ my ($cmd) = @_; my ($DEBUG) = 0; #$DEBUG = 1 if ($cmd =~ /nexsat/i); if ($DEBUG == 1){ use CGI; my $query = new CGI; print $query->header; } print "<p>Initially command = $cmd\n" if ($DEBUG == 1); # Need to untaint and run in a restricted environment { $cmd =~ /([\~\*\w\_\-\%\+\/\.\,\!\s\"\'\|\\\>\<\&]+)/; $cmd = $1; } print "<p>After untaint cmd = $cmd\n" if ($DEBUG == 1); my ($ORIG_PATH) = $ENV{'PATH'}; $ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin"; my (@RESULTS); # Remove any trailing | $cmd =~ s/\|\s*$//; print "<p>Really Running $cmd\n<p>" if ($DEBUG == 1); open(CMD,"$cmd 2>&1 |") || return ($!); print "Successfully opened $cmd\n" if ($DEBUG == 1); while(<CMD>){ chomp($_); next if ($_ =~ /sh /); next if ($_ =~ /grep /); print "<br>Pushing $_\n" if ($DEBUG == 1); push (@RESULTS,$_) if ($_ =~ /\w+/); } close (CMD); $ENV{'PATH'} = $ORIG_PATH; return (\@RESULTS); } ############################################################

This routine runs fine on "most" machines. It's just not running on a customer's.

Thank you for your help!

Replies are listed 'Best First'.
Re: Insecure Environment ?
by Anonymous Monk on Jul 22, 2014 at 22:07 UTC
    splain, diagnostics, they are for you :)
    Insecure $ENV{ENV} while running with -T switch at /u/beta/coampsos/COSL/COAMPSOS/lib/COAMPSOS_rmon_monitor_tools +.pm line 1496. (#1) (F) You can't use system(), exec(), or a piped open in a setuid or setgid script if any of $ENV{PATH}, $ENV{IFS}, $ENV{CDPATH}, $ENV{ENV}, $ENV{BASH_ENV} or $ENV{TERM} are derived from data supplied (or potentially supplied) by the user. The script must s +et the path to a known value, using trustworthy data. See perlsec.

    perlsec

Re: Insecure Environment ?
by kennethk (Abbot) on Jul 22, 2014 at 23:36 UTC
    Anonymous Monk's reference to perlsec is correct:
    The PATH isn't the only environment variable which can cause problems. Because some shells may use the variables IFS, CDPATH, ENV, and BASH_ENV, Perl checks that those are either empty or untainted when starting subprocesses.

    Likely your singular client is the only one whose shell is setting $ENV{ENV}.

    As a secondary note, rather than stashing and restoring values, you can use local to create a lexically dynamically-scoped version of the variable, meaning you don't have to worry about forgetting to restore a value. So maybe you want to write:

    local $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
    and $ENV{PATH} will be restored once the sub exits. As it stands, the path is clobbered if your open fails, and this would fix that. Or if you want to be thorough
    local @ENV{qw|PATH IFS CDPATH ENV BASH_ENV|} = '/bin:/usr/bin:/usr/loc +al/bin';

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      you can use local to create a lexically-scoped version of the variable
      Strictly speaking, local is dynamically scoped rather than lexically scoped.

      Dave.