Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Runtime Taint Enable

by BrentDax (Hermit)
on Feb 23, 2005 at 23:30 UTC ( #433902=note: print w/replies, xml ) Need Help??


in reply to Runtime Taint Enable

An answer of "You cannot" seems odd to me though. Perl doesn't normally keep you from doing dangerous things, even though they are dangerous.

While this is true, taint checking is something of a special case. When you turn on taint checking, you're specifically asking Perl to stop you from doing certain kinds of dangerous things. One of those dangerous things is to turn on tainting in the middle of your program--at that point it's essentially useless, because things that should have been tainted aren't! Hence, you're not allowed to turn on tainting in the middle of your program.

As the previous poster mentioned, you can use the ${^TAINT} variable to check if taint checking is turned on. (But as you implied, I'd recommend against doing so--there's nothing you should do when -T is on that you shouldn't also do with it off.)

=cut
--Brent Dax
There is no sig.

Replies are listed 'Best First'.
Re^2: Runtime Taint Enable
by Rhandom (Curate) on Feb 23, 2005 at 23:41 UTC
    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)];

      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)];

      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.

      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.)

Re^2: Runtime Taint Enable
by Anonymous Monk on Feb 24, 2005 at 13:25 UTC
    One of those dangerous things is to turn on tainting in the middle of your program--at that point it's essentially useless, because things that should have been tainted aren't! Hence, you're not allowed to turn on tainting in the middle of your program.
    That makes a lot of sense, but only if you're a god, and the start of a Perl program is the creation of the world. In reality, it's different. A system gets booted. It does a lot of things, including getting user input. After some time, a program is started with taint checking on. By stepping out the little box that your perl program is, you essentially are turning on taint checking in the middle of something.

    If that's ok, then turning taint checking on halfway your program should be fine too. For example, take an init.d script that first runs some (shell) commands, then starts a daemon written in Perl, using -T. From a conceptual view, tainting is turned on sometime after the script was started. And perhaps if you were to replace it with just one larger Perl program, you want to turn on taintchecking at the same point.

    I think the programmer should have finer control over what's considered tainted or not. Currently, it's all or nothing. But a daemon listening on some port might consider its environment, and any file it reads from the system safe (no need to untaint). But not what it gets from a socket. Or a program doesn't want to taint keyboard input, but it does consider the stuff it reads from the database to be tainted.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2022-01-20 12:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:












    Results (56 votes). Check out past polls.

    Notices?