develooper Front page | perl.perl5.porters | Postings from April 2008

Re: Taint (PL_tainting, SvTAINTED_on, SvTAINTED_off, SvTAINT)

Thread Previous | Thread Next
From:
Paul Fenwick
Date:
April 28, 2008 19:04
Subject:
Re: Taint (PL_tainting, SvTAINTED_on, SvTAINTED_off, SvTAINT)
Message ID:
481681FC.10501@perltraining.com.au
G'day Everyone,

Firstly, a little bit of history.  I'm not only a big user of taint, I'm a 
big advocate of taint.  We've been running a "Perl Security" course here in 
Australia for years, and for the first time at OSCON this year.  Taint is 
one of Perl's most useful features when working in a security sensitive 
context, so I'm fiercely interested in its workings.

Nicholas Clark wrote:

[snippage of things with which I agree]

 > Stuff pre-privilege drop doesn't matter, because
> it's (already) game over, hence why it doesn't matter that it's not tainted.

My issue here is that it may not _yet_ be game over.  Let's look at two 
situations, one where taint mode is immutable (it's either on or off for the 
entire program duration), and one where it can be switched on part-way 
through a program (late-acting taint).

In the immutable situation, if ${^TAINT} is true, then we know that an 
*untainted* piece of data has been sanitised in some way.  Either it's 
internal to our program (and safe), or we've taken special efforts to clean 
it (making it safe).

When taint can be switched on part-way through our program, we *don't know* 
what an untainted piece of data means.  It could have undergone careful 
scrutiny, or it could be some complete garbage that never got tainted.  We 
just don't know.

Why is this a problem?  Well, let's take the following code that wants to be 
paranoid.  It will *only* run in taint mode, and *only* execute its 
dangerous operation when it's sure that everything has been checked correctly:

     use Scalar::Util qw(tainted);

     sub do_something_dangerous {
         my @clean_args;

         ${^TAINT} or croak "I only run in taint mode";

         # If we have tainted args, sanitise them ourselves.
         # sanitised() croaks if anything looks fishy.

         if (grep { tainted($_) } @_) {
             @clean_args = sanitised(@_);

         # Otherwise, our args are already safe.
         } else {
             @clean_args = @_;
         }

         launch_tactical_strike_against(@clean_args);
     }

With late-acting taint mode, we could be executing this code with arguments 
that have *never* been sanitised, possibly with disastrous results.  With 
immutable taint, we either refuse to run the code at all (because ${^TAINT} 
is false), or we apply careful scrutiny to all the arguments.

The end result of late-acting taint is either:

	* A false sense of security: that any untainted data has been
	  undergone sanitisation if ${^TAINT} is true;  OR

	* The requirement to re-sanitise everything before performing
	  any dangerous operation, because we can no longer rely upon
	  taint-free data to actually be clean.

> However, Larry's logic is, that if you drop privileges, then you're stating
> that you now don't want the program to be running with the power of root...

But that's not what we're doing.  If we're fully dropping privileges by 
changing both our RUID and EUID, then late-acting taint doesn't activate. 
If we're RUID root, and (temporarily) drop our EUID to another user, then 
late-acting taint doesn't activate either.

It's *only* in the rather odd situation that we didn't start in taint mode, 
have changed our RUID to a non-root user, and our EUID (or EGID) doesn't 
match that late-acting taint comes into effect.

Since that's such an odd thing to do[1], I can *kind of* see this as a way 
of saying "we don't want to trust things now".  However I think it's an 
obscure and unexpected way of doing so, and not worth the loss of the 
assurances that we'd otherwise be able to expect if we see ${^TAINT} enabled.

I'd love for late-acting taint to be considered deprecated, and will 
cheerfully write a patch and tests if we reach this consensus.

Cheerio,

	Paul

[1] http://www.cs.ucdavis.edu/~hchen/paper/usenix02.pdf provides an 
excellent discussion the semantics of various unix privilege operations, and 
the most common transitions.

-- 
Paul Fenwick <pjf@perltraining.com.au> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About