Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Think beyond Taint and warnings

by rob_au (Abbot)
on Sep 14, 2001 at 18:43 UTC ( [id://112434]=perlmeditation: print w/replies, xml ) Need Help??

I came across an interesting point to meditate upon this evening while reading through the Perl source to some applications I had downloaded for review. I'll paste a slightly-edited snippet of the code, edited only to obscure its source, which piqued my thoughts:

#!/usr/bin/perl -w . . # Do some things to make Taint happy: delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; . . my(%options); getopts('nhkf:p:', \%options); if($options{'k'}) { # kill running program. my($pid) = `cat $HOME/program.pid`; if($pid =~ m{([0-9]+)}) { $pid = $1; } kill 'INT', $pid; exit(0); }

Now what caught my interest with this code, was that while it appears it was written to execute under Perl with the taint (-T) and warnings (-w), it falls horribly short of the secure code that the author was obviously intent on producing. This code, designed to obtain the process ID of the current invocation of the application and terminate its execution, falls short on many levels.

Most notably, the code, while comments within it suggest it has been written to run under taint mode, has not been invocated as such - That is, the #!-shebang path to the Perl interpreter does not pass the -T taint switch. However beyond this, in the segment of code intended to actually obtain the process ID of the invoked application and kill it, major flaws in logic negate any worth which taint mode execution could offer.

my($pid) = `cat $HOME/program.pid`; if($pid =~ m{([0-9]+)}) { $pid = $1; } kill 'INT', $pid; exit(0);

Firstly, this segment of code relies on an external application to return process ID of the application from the program.pid file in the application home directory. Now while this itself is not a crime, and I should note that the program author has cleaned up the environment path, it shifts the burden of responsibility off to the external application to return the correct value.

Furthermore, while the author had the foresight to check that the returned value is indeed a number, there is no check to see whether this is a valid process ID, the process ID of the invoked application (remember, the external file and application on which the dependency for this value has been placed may have been modified outside the bounds of our code logic) or indeed provided correct fall-through in the event of a maligned process ID being returned. Indeed, should one feel so inclined and depending on the execution rights of this code, which given the application could be priviledged, it would be relatively easy to turn this application into a tool for misdemeanour.

In short, the content of this meditation are thus

  • Don't rely solely on taint to clean up your code - The major problems with this code and indeed as to why it most likely will not run cleanly under taint mode are related to programmer logic moreso than 'dirty' data.
  • Think your code through, rationale and evaluate your logic and process flow and build your code accordingly.
  • In the process of code development and debugging, taint is your ally, treat your ally as a friend, not an enemy.

Your thoughts and comments on the value and application of taint and programmer logic in securing code are welcomed.

 

 

Ooohhh, Rob no beer function well without!

Replies are listed 'Best First'.
Re: Think beyond Taint and warnings
by echo (Pilgrim) on Sep 14, 2001 at 19:13 UTC

    I think it's worth mentionning that:

    delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
    is not safe practice. With this code we still don't know what's left in %ENV, possibly a malicious environment variable can remain that will affect an application in unforeseen ways. One should not remove information one thinks is unsafe, but rather explicitely set information known to be safe. This is exactly the same mistake as trying to remove unsafe characters from a string before passing it to a shell: the secure way is to do the opposite, remove any character which is not from a known safe set. In the %ENV example I suggest recreating the hash from scratch with known safe values.

Re: Think beyond Taint and warnings
by perigeeV (Hermit) on Sep 15, 2001 at 14:20 UTC

    Using the /full/path/to/the/program cures a host of ills.


      this is true! but i would think that it would be far safer if the perl code itself were to accomplish the same function as the 'outside program. yes, i realize that sometimes that is at times wasteful of system resources, as well as the programmer's time, but for something as simple as the example here (getting the process ID of said program) it would be best, imho.

      especially since perl is so good at handling and sorting human readable data. also, it's entirely possible that somewhere along the line, that program might be moved or updated, and the updated binary could be in a new location; say, the old might be in /usr/bin, and the new could be in /usr/local/bin - change paths to taste for win32 platforms. not every installation/upgrade for a program/suite is as intelligent as perl's is. (: (eg, asking user and/or admin if it should create a symbolic link to the location of the old binary)

      but hey! that's just my $0.25. and it might be worth only a nickel in some currencies. (:
      strfry()

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://112434]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-03-19 04:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found