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 15, 2008 06:56
Subject:
Re: Taint (PL_tainting, SvTAINTED_on, SvTAINTED_off, SvTAINT)
Message ID:
4804B3B6.9070103@perltraining.com.au
G'day Nicholas / p5p,
Nicholas Clark wrote:
> Well, it seems to be something Larry wanted:
>
> http://public.activestate.com/cgi-bin/perlbrowse/b;p=524,2687/mg.c@1528#L
>
> and (as best I can work out that code) it gets turned on automatically
> whenever you're not root, and either your user IDs don't match, or your group
> IDs don't match.
That makes sense during start-up. If our EUID and RUID don't match then
we're running setuid (or with some other oddness), and we should be very
careful. It makes sense to act with caution when our data is being provided
by one set of privileges, but we're running with another.
> in addition to that. I'd infer that it's intended to add taint mode for people
> who aren't aware of it, rather than to be any recommended way to enable taint.
Again, sensible during start-up. But not sensible afterwards. For example:
#!/usr/bin/perl -wl
use Scalar::Util qw(tainted);
print "Taint is ${^TAINT}";
$< = 1001;
print "Taint is now ${^TAINT}";
print "My path is $ENV{PATH}";
print "Path taint is ",tainted($ENV{PATH});
__END__
When run as root, this cheerfully informs me that my path is completely
clean. Tweak it for @ARGV, and everything in there is clean too.
I can't see WHY you'd want to enable taint mode, but have all the things
you'd never want to trust considered clean that was set before that point.
What makes it worse is because they're all clean, an arbitrary part of the
program can't tell if a piece of data has been properly sanitised; the
information is simply not there.
> I'm not convinced on the "false sense of security" part.
I am! I use taint mode (along with 'use re qw(taint)' to protect against
accidental untainting) for:
* Protection against mishaps where environment variables are
set when they shouldn't.
* Protection against mishaps where data from my database
may end up near something executing as code (ie, the shell).
* Protection against data entering my database before being
properly validated and normalised.
* Segmentation between unvalidated and validated data.
* A whole swag of protections when it comes to the filesystem.
* Protection against accidental mishaps with <> in an
untrusted environment.
* Many of the above happening in modules that my code
is using, even if I haven't written those modules.
You're right that taint is no substitute for thinking. However taint isn't
meant as a substitute, it's meant as a safety belt; potentially catching the
things that one didn't expect. I regularly replace Perl's built-in open
with one that checks all arguments for taintedness before opening[1]. That
certainly SHOULD make it more difficult for me to accidentally open the
wrong file and disclose data I may regret.
Imagine the following subroutine:
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 (map { tainted($_) } @_) {
@clean_args = sanitised(@_);
# Otherwise, our args are already safe.
} else {
@clean_args = @_;
}
launch_tactical_strike_against(@_);
}
Here it's fine for us to pass in tainted data, it'll get laundered
automatically. But if taint mode had started 'part-way' through the
program's execution, the data we've passed in may not be sanitised, but it
may not be tainted, either. That's very, very bad.
I personally find it chilling to think that taint mode could be turned on
part-way through a program, where I've potentially already loaded code that
I didn't want (via PERL5LIB), and all the data I'd like to check (eg, user
or network input) has already been marked as clean. I would much rather
perl leave the taint switch off when changing unix privileges, so ${^TAINT}
can reliably indicate if we started in taint mode.
Perl requires that a program with -T on the shebang line must also be
started with -T on the command line for this very reason. I certainly hope
we're not planning to change that behaviour!
I still maintain that changing perl's tainting behaviour after it's already
started is a bug, and breaks the fundamental design principles of taint.
Cheerio,
Paul
[1] The standard behaviour is to skip taint checks if a file is open for
reading. You can even get creative and duplicate an existing filehandle
using tainted data if you open something like "<&=0".
--
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