Nathan Wiger <[EMAIL PROTECTED]> writes:

[...]

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

This is very different from the current model.  perlsec talks about
"tainted *data*", not " tainted *variables*" (my emphasis).  I believe 
it does so for a reason -- it does not make sense to talk about
variables (if $x is tainted variable, how can "$x+2" be tainted
without being a variable?).  In this way, we can talk about operations 
which remove taintedness (substring extraction using m/.../), and the
others which preserve it.  I doubt the same could be done for
variables.  Some expressions don't even involve a variable!  For
instance, your "read_unsafe_value()" has no variables, tainted or
untainted, in sight; why is it unsafe?

Unfortunately, this would mean your example above doesn't quite work.
One possibility is to say that $^T controls taint *checking*, but not
tainting itself[1]!  That is, in the above code $trick_var's value is
tainted.  Now you say "$^T=1; $ENV{PATH} = $trick_var;", which is
insecure (attempting to set $ENV{PATH} from an insecure value while
taint checking is on).

> 
>    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 ????

Here, $^T=0, so no taint-checking is done (sorry).  Even "$ENV{PATH} =
$unsafe_value;" would work (sorry again)!

[...]

Another note: your examples with:

        local ($^T) = 0;
        $ENV{PATH} = read_config_file();
        local ($^T) = 1;

is only using local() to confuse; it should be written with a block,
correctly restoring the old value of $^T.


Footnotes: 
[1]  For efficiency, you'd probably still want some command-line
option, perhaps -T itself, to say "this program involves taint
checking, so please keep track of tainted values".  That way programs
that keep $^T == 0 (almost all of what I write) don't need to keep
track of tainting.

-- 
Ariel Scolnicov        |"GCAAGAATTGAACTGTAG"            | [EMAIL PROTECTED]
Compugen Ltd.          |Tel: +972-2-6795059 (Jerusalem) \ We recycle all our Hz
72 Pinhas Rosen St.    |Tel: +972-3-7658514 (Main office)`---------------------
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555    http://3w.compugen.co.il/~ariels

Reply via email to