in reply to Re: Runtime Taint Enable
in thread Runtime Taint Enable

As a devil's advocate and ignoring problems with PERLLIB and PERL5LIB, in a CGI enviroment I can do many things before I read any input from the user. So as long as taint is enabled by the time I read input from the user then the dangerous data is taken care of. There are only so many sources of input to control and it is an easy process to mark untainted items as tainted.

Thanks for your response. ++ to you.

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

Replies are listed 'Best First'.
Re^3: Runtime Taint Enable
by hv (Prior) on Feb 24, 2005 at 14:53 UTC

    Hmm, interesting: I confess I don't use tainting in my CGI scripts despite the common recommendations, and this is part of the reason why - the data sources I want to choose not to trust are a small fraction of the whole, and the maintenance cost of detainting everything seems too high to me.

    With the caveat that perl is not written with the intention of supporting this, I found the following simple test gave me the results I expected:

    #!/usr/bin/perl -w use strict; use Scalar::Util qw/ tainted /; use Inline C => 'void starttaint() { PL_tainting = 1; }'; my $line = <>; print "line tainted: ", tainted($line), "\n"; print "\$0 tainted: ", tainted($0), "\n"; starttaint(); $line = <>; print "line tainted: ", tainted($line), "\n"; print "\$0 tainted: ", tainted($0), "\n";

    It is trickier if you want to taint a data structure after having turned on tainting late: the normal way to taint a variable is to wave another already-tainted variable at it, but in this case you might not have one. The simplest way to achieve that is to add another Inline function to create one:

    SV* taintvar() { PL_tainted = 1; return newSVpvn("", 0); } ... # perl code starttaint(); my $tv = taintvar(); sub taintme { wantarray ? map($_ .= $tv, @_) : $_[0] . $tv }

    I repeat, perl was not written with the intent of supporting such usage, and the behaviour may easily change between perl versions, platforms and phases of the moon.

    Hugo

      Hmm, interesting: I confess I don't use tainting in my CGI scripts despite the common recommendations, and this is part of the reason why - the data sources I want to choose not to trust are a small fraction of the whole, and the maintenance cost of detainting everything seems too high to me.
      I wonder whether there's a need for IO layers that can be used to create "tainted" data streams, and "untainted" data streams. (You still would have to consider $0 and the various environment variables though).
      All I could say was wow! If I could ++5 I would. Thank you for the code. Very nice.

      It would be very nice to be able to do this. I might take your code and make a module out of it (Nice - extremely short module). If people wanted it could even go on CPAN.

      How about Taint::Runtime.

      my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re^3: Runtime Taint Enable
by sgifford (Prior) on Feb 24, 2005 at 04:18 UTC

    I agree. It's useful to provide configuration information through the environment, and there's no danger (as long as you don't use environment variables that are set automatically based on the Web request).

    I often simply blindly untaint data from environment variables I know are safe, and convert PERL5LIB into a series of use lib commands. That's the technique I would recommend.

    It would be useful if Perl's mechanism for handling tainted data was more flexible, to better handle these situations.

Re^3: Runtime Taint Enable
by thor (Priest) on Feb 24, 2005 at 12:23 UTC
    You assume that users are the only place to get tainted data from. Any external data can (and should) be marked as tainted. This includes but is not limited to: the results of system calls, database results, and anything that is derived from these. Basically, anything that came from outside your program should be viewed as suspect when thinking about taint.

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

      Any external data can (and should) be marked as tainted. This includes but is not limited to: the results of system calls, database results, and anything that is derived from these. Basically, anything that came from outside your program should be viewed as suspect when thinking about taint.
      That I disagree with. If I'm in full control of my box, I may consider any file (especially configuration files) on the box to be safe (and if I couldn't, why would I trust /usr/bin/perl?). I might consider all modules safe. All environment variables to be under my control. But not the data that I'm reading from a socket, because that's outside of my control.

      There are a lot of situation where I turn on taint checking because there's a limited amount of external data that I consider tainted. (Basically, this boils dows to the fact that what is external data for me doesn't coincide with what Perl considers to be external data - and I don't blame Perl for that, because Perl can't know.)

        Okay...I'll bite. Consider the following program:
        use warnings; use strict; foreach my $file (<*>) { if ($file =~ m/(.*)/) { #we trust everything from *our* box $file = $1; my $rc = system("rm", $file); } }
        Now consider this file listing:
        -rw-rw-r-- 1 thulben thulben 1 Feb 24 11:03 -rf -rwxr-xr-x 1 thulben thulben 254 Feb 24 10:59 unsafe.pl*
        Whoops!

        thor

        Feel the white light, the light within
        Be your own disciple, fan the sparks of will
        For all of us waiting, your kingdom will come