Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Tainted variable

by Eureka_sg (Monk)
on Apr 16, 2001 at 18:51 UTC ( [id://72828]=perlquestion: print w/replies, xml ) Need Help??

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

This is taken from perlfaq7

sub is_tainted{ return ! eval {join('',@_),kill 0;1;}; }

Can anyone explain how the above subroutine checks for tainted data?

Replies are listed 'Best First'.
Re: Tainted variable
by Dominus (Parson) on Apr 16, 2001 at 20:34 UTC
    return ! eval {join('',@_),kill 0;1;};

    The really interesting thing here that I think nobody commented on yet is that this works because taintedness is only computed per-statement, not per-expression. Perl has a flag inside it called tainted. Whenever Perl starts a new statement, it clears the flag. Whenever Perl accesses tainted information, it sets the flag. Whenever Perl performs an 'unsafe' operation, it checks the flag and throws an exception if the flag is set.

    This means that if you access tainted information in a statement, and then perform an unsafe operation in the same statement, Perl will throw the exception even when the tainted infotmation couldn't possibly affect the outcome of the unsafe operation, as in your example.

    (Why was it done this way? For efficiency and ease of implementation.)

    This oddity is used here to test possibly malicious data in conjunction with an unsafe operation, but in such a way that the data can't possibly affect the result of the operation, so that it's safe.

    Happy Bicycle Day!

      Thanks for the clear explanation! :-)

Re (tilly) 1: Tainted variable
by tilly (Archbishop) on Apr 16, 2001 at 19:25 UTC
    See perlsec.

    In this case they were looking for a way to bring tainted data in contact with a system command in a way that was absolutely safe, but would still trigger the taint test. If you hit the taint test you bomb out and get a false value. If you don't then you survive to the true return. Flip the truth and voila!

    Incidentally I disagree with them on their comment about warnings. Consider the following test:

    sub is_tainted { eval { () = (join('',@_), kill 0) }; if ($@) { if ($@ =~ /^Insecure dependency/) { return 1; } else { die $@; } } else { return 0; } }
    Not only does this pass warnings, but it at least tries to handle the possibility of other things going wrong. (eg a platform where kill is not implemented...)
      Says tilly:
      a platform where kill is not implemented...
      It may be interesting to note that there's no reason why kill 0 can't be implemented on any system, even one that doesn't support other uses of kill.

      I wouldn't bother pointing this out, except that Chris Nandor added kill 0 support to MacPerl just a couple of weeks ago, for precisely this purpose.

      --
      Mark Dominus
      Perl Paraphernalia

Re: Tainted variable
by Rhandom (Curate) on Apr 16, 2001 at 19:29 UTC
    Seems like a big overhead. You should be checking you own variables for tainted'ness. From the perlfaq7:
    Here's an example (which doesn't use any system calls, because the kil +l() is given no processes to signal).
    Tainting occurs if you try and pass any uncontrolled information to the system interpreter. The use of kill 0 attempts to trick the perl interpreter into thinking that you are passing sensitive information (@_) to the system. If tainting fails, it will cause the script to halt execution right then and there -- so the block is wrapped in an eval block. If the data is safe, the join('',@_),kill 0; will not die and the block will return the last value of "1" signifying that the data is not tainted, this is negated with the "!" and returned as the value. If the data was tainted, the block would haved died and the eval would return undef.

    That said, this might be a nice generic way to do it, but really you should be checking anything that you are passing to the interpreter yourself (using regex or other methods). This way you can already be preparing passed information for safe passage to the system level.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2024-04-25 12:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found