in reply to Re: tainted entangled hashrefs
in thread tainted entangled hashrefs

Thanks, your explanation does help. However it seems that in my example $foo is not tainted, (its value is "HASH(0x80f8a20)") - only the values of the hash reference are tainted (%$foo has become dirty because the value of one of the keys was bad). I think you knew this.

Your explanation does mean I can push the tainted data down a level to clean up my hash-ref, eg:
$dirty{text} = <>; $foo = { 'clean' => '/home/boldra/filename.txt', 'dirty' => \%dirty, }; open(F,"+>{$foo->{clean}}"); close(F);
Which leaves $foo->{clean} clean as a whistle.

But I still don't see why I have to do this. Is it because taint checking is simply clumsy, or is there actually a risk of a user supplying data that perl will accidentally interprect as the boundry between two values in an array?

What I'm worrying about is: Is $foo->{clean} really tainted (in my original example) or is it a false positive by the taint-checking? If it's really tainted - what sort of cleaning does it need?

Thanks,

- Boldra

Replies are listed 'Best First'.
Re: Re: Re: tainted entangled hashrefs
by herveus (Prior) on Aug 22, 2001 at 20:48 UTC
    I tested the following with "dirty" commented and uncommented:

    #!/usr/bin/perl -wT use strict; my $foo = { clean => 'test.dat', # dirty => scalar(<>), }; open (F,"+>{$foo->{clean}}"); close(F);

    As shown here, it ran with no error. That tells me that $foo->{clean} really is taint clean.

    yours,
    Michael

      I get an error if the "dirty" line is not commented, using perl 5.005_03, 5.6.0 and 5.6.1.

      - Boldra
Re: Re: Re: tainted entangled hashrefs
by MZSanford (Curate) on Aug 23, 2001 at 12:43 UTC
    from my understanding, this is mostly a problem with Taint-checking being clumsy. using <> does not give the input line the ability to modify %foo (unless you eval'd it and then it would taint anything it touches), so the keys other than dirty should stay clean, but they do not. I believe this is an implimentation detail (or bug?) in taint checking that makes all keys in a hash share the same taint-state. Maybe someone with a bit more source knowlege could confirm that ? I will start check source myself, and will post an update if i find anything.

    Update : Now i am getting too far into this (Trees? What trees ? i am in a forest !), and have found that normal hashes do not suffer this. So, in Perl 5.6.0 i used :
    %ENV = (); %foo = ( clean => '/usr/matt/.netrc', dirty => (<>), ); print "$foo{clean}\n"; sleep 1; print "$foo{dirty}\n"; sleep 2; system("ls $foo{clean}"); # ok system("ls $foo{dirty}"); # error
    but failed on a hash ref. ... still looking.


    Update Again : Ok, here is an odd one, here is my test code :
    $| = 1; %ENV = (); %foo = ( clean => '/usr/matt/.netrc', dirty => (<>), ); $bar = { clean => '/usr/matt/.profile', dirty => (<>), }; $and = \%foo; print "Foo\n"; print "1 : " ; system("echo $foo{clean} > /dev/null 2>&1"); print "2 : " ; system("echo $foo{dirty} > /dev/null 2>&1"); print "Bar\n"; print "1 : " ; system("echo \"$bar\" > /dev/null 2>&1"); print "2 : " ; system("echo $bar->{clean} > /dev/null 2>&1"); print "3 : " ; system("echo $bar->{dirty} > /dev/null 2>&1"); print "And\n"; print "1 : " ; system("echo \"$and\" > /dev/null 2>&1"); print "2 : " ; system("echo $and->{clean} > /dev/null 2>&1"); print "3 : " ; system("echo $and->{dirty} > /dev/null 2>&1");
    And the output is :
    %shell > perl -Du -U -T taintme.pl EXECUTING... a ^D b ^D Foo 1 : system 0 30004 30004 2 : system 1 30004 30004 a Bar 1 : system 0 30004 30004 2 : system 1 30004 30004 3 : system 1 30004 30004 And 1 : system 0 30004 30004 2 : system 0 30004 30004 3 : system 1 30004 30004 a
    I am now seeing this is something with the anonhash specifically, and assiging a hash-ref to an extsing hash will allow key access. Unsure why.

    Update 3: anymore updates and i will create a new node. I added some code to my last test script and got yet another oddity. I added :
    $another = +{}; $another->{clean} = '/usr/matt/.kshrc'; $another->{dirty} = (<>); # and also print "1 : " ; system("echo \"$another\" > /dev/null 2>&1"); print "2 : " ; system("echo $another->{clean} > /dev/null 2>&1"); print "3 : " ; system("echo $another->{dirty} > /dev/null 2>&1");
    and to my suprise i got :
    Another 1 : system 0 30004 30004 2 : system 0 30004 30004 3 : system 1 30004 30004
    ... so, now i think it is a bug in how tainting is assigned during the assigment. Maybe it taints everything in the {} block as a group ? thats about all i have at this point. hmmm... looking at perl -Dut -U -T taintme.pl i see that the code is parsed, and not until the end of the block it is decalred a anonymous hash. So, because it could be a code ref (maybe? i'm guessing) the taint covers the whole block. My fix is to assign dirty element seperatly line $another above.

    Update (last) : Per CB request , here is the fix fo the code :
    Taint bad ...
    #!/usr/bin/perl -wT # use strict; my $foo = { 'clean' => 'filename.txt', 'dirty' => scalar(<>), }; open(F,"+>{$foo->{clean}}"); close(F);

    ... and taint ok ...
    #!/usr/bin/perl -wT # use strict; my $foo{clean} = 'filename.txt'; $foo{dirty} = scalar(<>); open(F,"+>{$foo->{clean}}"); close(F);

    can't sleep clowns will eat me
    -- MZSanford