Dan Sugalski wrote:
>
> > existence of a $^T variable for controlling tainting in the same way
> > that $^W controls warnings.
>
> So put in an RFC. :)
Dan-
Ask and ye shall receive...in POD format ala Tim...
BTW, I've posted this to both lists because your reply was. However,
since $^T wouldn't remove any functionality, unless someone had already
planned a use for it, further discussion can probably stay on
perl6-internals for now (unless you feel otherwise). Please CC: me as
I'm not on the internals list.
-Nate
=head1 TITLE
Allow on-the-fly tainting via the $^T variable
=head1 VERSION
Maintainer: Nathan Wiger <[EMAIL PROTECTED]>
Date: 31 July 2000
Version: 1
Mailing List: perl6-internals
Number: 1
=head1 Abstract
Currently, Perl requires that tainting be invoked along with the Perl
interpreter, via the -T switch. It would be nice if tainting could be
turned on and off at will via the $^T variable, just like $^W can be
used to toggle the -w warning flag.
=head1 Description
Because of the way tainting works, tracing all variables from inception
through destruction, right now tainting can only be turned on or off
globally via the -T switch. This leads to many problems, however, such
as reading a variable from a known-safe configuration file. For example:
#! perl -T
$ENV{PATH} = read_config_file();
is basically guaranteed to generate an "Insecure dependency in ..."
error.
The current workaround is the sacred untainting trick, i.e.
#! perl -T
my $unsafe = read_config_file();
($ENV{PATH}) = $unsafe =~ m#^(.*)$#s; # untaint
However, as mentioned this is a workaround. While neat, it's still a
workaround...
Instead, it would be really cool if Perl6 let you do this:
#! perl -T
local($^T) = 0;
$ENV{PATH} = read_config_file();
local($^T) = 1;
Which would lead to several nifty side effects, such as:
#! perl
# turn on tainting only if the user said to
$^T = 1 if $r->dir_config('PerlTaintChecks');
Hmmmmmm....
=head1 Implementation
This will avoid internals, but instead get into the details of how the
implementation should *act*:
1. Have the tainting engine "trust" any variables declared
when tainting is off. So:
#! perl
# engine assumes this is clean
my $var = 'some_val';
$^T = 1;
$ENV{PATH} = $var; # safe
So, the tainting engine could trust $var just as if it
had been the string '/usr/bin:/usr/sbin'.
2. Nonetheless, have the tainting engine watch any tainted
variables still. So, whatever scope (tainted or untainted)
the variable is *initially declared in* is what it remains
as:
#! perl -T
# this doesn't work, sorry
my $unsafe_value = read_unsafe_value();
$^T = 0;
my $trick_var = $unsafe_value; # try to sneak...
$^T = 1;
$ENV{PATH} = $trick_var; # nope! insecure still!
That way, the $^T variable would not allow someone to
easily shoot themselves in the foot by accidentally
untainting the wrong thing.
3. A true RFC: What to do about this?
#! perl -T
my $unsafe_value = read_unsafe_value();
$^T = 0;
my $trick_var = $unsafe_value; # try to sneak...
$ENV{PATH} = $trick_var; # ???? ok ????
The question here is: should stuff be implicitly tainted
once tainting has been activated anywhere? There are two
possibilities for setting $^T = 0:
a) all tainting is turned off (like $^W)
b) tainting for NEW OBJECTS ONLY is turned off
So, under (a), the above would work fine, since tainting
has simply been turned off. This is probably the most
intuitive way to implement it.
Idea (b) is a little more fancy. Here, existing objects
that have already been tainted remain tainted. This just
takes item #2 to the next step. The main difference is
that (b) has a more "follow each variable" semantic to
it. So, basically, once -T or $^T was specified, the
tainting module would be active throughout the life
of the script and watch any and all variables declared
while $^T, even if $^T later = 0.
=cut