Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

perlsec question

by Anonymous Monk
on Dec 14, 2001 at 00:21 UTC ( #131746=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

In perlsec it say to delete some of the %ENV keys.
What are these and why are they dangerous? I guess they have to do with the shell, so I think they don't matter if I do not use the shell, right?

Replies are listed 'Best First'.
Re: perlsec question
by no_slogan (Deacon) on Dec 14, 2001 at 00:58 UTC
    ENV and BASH_ENV give the names of files that are executed when a new shell is started. Someone could point one of those to a file full of evil commands.

    CDPATH gives a search path for the cd command. Changing that could make shell scripts switch into unexpected directories.

    IFS gives a list of "internal field separators", which the shell treats like spaces. Here's a link that tells how to exploit this feature.

    Yeah, they have to do with the shell. If you call any external programs, can you be absolutely certain that none of them will invoke a shell?

    I doubt that this is a complete list of problem environment variables. It's probably best to delete everything you aren't sure is safe.

    %ENV = map { ($_, $ENV{$_}) } grep exists($ENV{$_}), qw(THIS THAT THE_OTHER);
    ...or something of that sort. Anyone have any suggestions of environment variables that will cause problems if they aren't kept? TERM? USER? HOME?
Re: perlsec question
by hawson (Monk) on Dec 14, 2001 at 02:57 UTC
    They all deal with shells, and executing external commands. If you are 100% sure that you do not execute any external commands at all, then you don't need to worry about them. This means that your code can't have any system or exec, but you should also be wary of open, and (I think) syscall.
    • $IFS is the "Internal Field Seperator" used between fields on a command line. For example, if you set IFS="/", then /usr/bin/ls becomes "usr bin ls". This happens before the shell looks for the command in the path, so if someone can place a command called "usr" in the path, that will be executed instead of what you intended.
    • CDPATH is to the 'cd' command as $PATH is to executing a command. An example:
      [jbecker@deadlands /]$ echo $CDPATH /home/jbecker [jbecker@deadlands /]$ pwd / [jbecker@deadlands /]$ file /home/jbecker/pilot /home/jbecker/pilot/: directory [jbecker@deadlands /]$ cd pilot /home/jbecker/pilot [jbecker@deadlands pilot]$ pwd /home/jbecker/pilot
      This could be bad if you use relative directories within your code and execute things within them. I expect this is more of a shell programming issue, but it can bite you with perl as well.
    • $ENV usually is the full path to a file that gets executed by certain shells (MKS Korn shell at least) before it (the shell) does anything else. This could easily be used to create a setuid root shell if something is tricked into running a shell as root that, in turn, executes the $ENV file.
    • $BASH_ENV: from the bash man page:
      When bash is started non-interactively, to run a shell script, +for example, it looks for the variable BASH_ENV in the environment, expands its value + if it appears there, and uses the expanded value as the name of a file to read and e +xecute. Bash behaves as if the following command were executed: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi but the value of the PATH variable is not used to search for th +e file name.
      It's the same, essentially, as ENV. Icky.
Re: perlsec question
by Rhandom (Curate) on Dec 14, 2001 at 03:02 UTC
    Another place that you can see it manifest is in the following script:

    #!/usr/bin/perl -w -T use strict; print "hello ($0)\n"; #delete $ENV{$_} for qw(PATH BASH_ENV); # may need to add more to list, PATH and BASH_ENV # were all that drove my system crazy exec "$1 foo" if ! @ARGV && $0 =~ m|^([\w\/\.]+)$|;

    Save this into a file and try to run it. It will fail until you uncomment that line. Otherwise, you could be syscalling or execing using unsecure information in the PATH and BASH_ENV variables.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];

Re: perlsec question
by belg4mit (Prior) on Dec 14, 2001 at 04:52 UTC
    People have told you what they are, good. IMHO however you are much better off resetting %ENV. Kill it, %ENV = ();. This way you know for sure you aren't passing anything bad. Or at the very least, explicitly pass only things you know are safe or you have sanitized.
    my @PATH = ($ENV{PATH} =~ m/clean/); %ENV = ( PATH => join(':', @PATH); );

    perl -p -e "s/(?:\w);([st])/'\$1/mg"

      I should think that clearing %ENV would eventually bite you in the butt when you start using the code in question to run programs that depend on the environment.

      Granted there are times when it's appropriate -- running children from a setuid program, for example -- but most of the time it's just too big a hammer.

          -- Chip Salzenberg, Free-Floating Agent of Chaos

        When all you have is a hammer everything looks like a nail :-D. Except of course having a swiss army chainsaw there is more than a hammer at our disposal. However, it surely cannot be too difficult to later clean and pass other environment variables as needed. Else one could say not clearing %ENV will eventually bite you in the butt because you have no idea what some clever author of an external program will rely upon and do with an environment variable ;-).

        perl -p -e "s/(?:\w);([st])/'\$1/mg"

Re: perlsec question
by strat (Canon) on Dec 14, 2001 at 15:38 UTC
    And by killing %ENV, you also kill your cgi-Parameters, and so communication between cgi-Scripts is nearly impossible.

    Best regards,
    perl -e "print a|r,p|d=>b|p=>chr 3**2 .7=>t and t"

      Nah. Get your CGI parameters first, then kill %ENV before doing anything.

      You can always explicitly set any ENV variables you need anyway (and should) and you should always specify the full path to any executables you use.

      Regards, Helgi Briem

      If you have CGI scripts trying to execute other CGI scripts, then you are doing something fundamentally wrong already.

      Not to mention that CGI scripts which assume that all CGI communication will be in %ENV loses you the ability to pass large amounts of data to the script. (Which requires the POST method to do.)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://131746]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2017-08-17 21:47 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (293 votes). Check out past polls.