eskwayrd has asked for the wisdom of the Perl Monks concerning the following question:

I'm exploring Perl's taint mode, and how to use it effectively. Unfortunately, I've come across a situation that disgrees with the available taint documentation; using hash keys can cause external data to be untainted.

I'm using Perl v5.6.1 on a RedHat Linux 7.1 box.

Could someone please enlighten me as to why external data that is known to be tainted becomes untainted when used as a hash key?

Below is a short script to demonstrate the situation:

#!/usr/bin/perl -T use strict; use warnings; # taken from Programming Perl, 3rd edition, p 561 sub is_tainted { my $arg = shift; my $nada = substr($arg, 0, 0); local $@; eval { eval "# $nada" }; return (length($@) != 0) ? 'tainted' : 'not tainted'; } my %hash = (); open FILE, $0 or die "cannot open $0: $!"; while (my $line = <FILE>) { chomp $line; warn is_tainted($line); $hash{$line} = is_tainted($line); } close FILE; foreach my $key (keys %hash) { warn is_tainted($key); }
When executed, the following output is generated:

tainted at ./taint_test.pl line 19, <FILE> line 1. tainted at ./taint_test.pl line 19, <FILE> line 2. tainted at ./taint_test.pl line 19, <FILE> line 3. tainted at ./taint_test.pl line 19, <FILE> line 4. tainted at ./taint_test.pl line 19, <FILE> line 5. tainted at ./taint_test.pl line 19, <FILE> line 6. tainted at ./taint_test.pl line 19, <FILE> line 7. tainted at ./taint_test.pl line 19, <FILE> line 8. tainted at ./taint_test.pl line 19, <FILE> line 9. tainted at ./taint_test.pl line 19, <FILE> line 10. tainted at ./taint_test.pl line 19, <FILE> line 11. tainted at ./taint_test.pl line 19, <FILE> line 12. tainted at ./taint_test.pl line 19, <FILE> line 13. tainted at ./taint_test.pl line 19, <FILE> line 14. tainted at ./taint_test.pl line 19, <FILE> line 15. tainted at ./taint_test.pl line 19, <FILE> line 16. tainted at ./taint_test.pl line 19, <FILE> line 17. tainted at ./taint_test.pl line 19, <FILE> line 18. tainted at ./taint_test.pl line 19, <FILE> line 19. tainted at ./taint_test.pl line 19, <FILE> line 20. tainted at ./taint_test.pl line 19, <FILE> line 21. tainted at ./taint_test.pl line 19, <FILE> line 22. tainted at ./taint_test.pl line 19, <FILE> line 23. tainted at ./taint_test.pl line 19, <FILE> line 24. tainted at ./taint_test.pl line 19, <FILE> line 25. tainted at ./taint_test.pl line 19, <FILE> line 26. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25. not tainted at ./taint_test.pl line 25.

Replies are listed 'Best First'.
Re: Unexpected de-tainting with hash keys
by sauoq (Abbot) on Jul 11, 2003 at 02:03 UTC

    Uh... Eek!?

    For a shorter example:

    $ perl -lTe 'eval(+shift)' -- 'print "hi"' Insecure dependency in eval while running with -T switch at -e line 1. $ perl -lTe '$h{+shift} = 1; eval $_ for keys %h' -- 'print "uh oh"' uh oh
    and that's 5.8.0.

    -sauoq
    "My two cents aren't worth a dime.";
    

      ++ to you: not only is it shorter, it proves the significance of this bug as it shows execution of tainted data.

      Apparently the stringification of hash keys is untainting this while providing no safety.

      Eek indeed.

      --Bob Niederman, http://bob-n.com
        You nailed it. The hash key is a string and not a scalar. See my post below.


        TGI says moo

Re: Unexpected de-tainting with hash keys
by TGI (Parson) on Jul 11, 2003 at 02:24 UTC
    This is mentioned in my copy of the Camel (the most recent ed. whichever that is). Taint, blessedness and all the other little things that make perl scalars neat do not apply to hash keys coz they're just plain old strings. Hash keys are not scalar values.

    I tried to find some good documentation to support myself with, but this is clearly not well documented behavior. Dominus mentions it in his September 1 1998 Line of the day (scroll down). There's also a note in an old version of the Taint module. I couldn't find anything more recent. But it is in the latest Camel, I don't have my copy handy or I'd find a page # for ya.


    TGI says moo

      Indeed, it is known. Wow.

      At the very least, the docs should be patched. At least that's an easy "fix." :-)

      -sauoq
      "My two cents aren't worth a dime.";
      
      Thanks for the explanation. This makes it seem so obvious.

      And, the page number in question for the 3rd edition of the Camel book is 559. It's the last sentence in the second to last paragraph. I'd been over that section a few times and completely missed the implication.

      And the links to MJD's page and to the old Taint documentation were helpful too.

Re: Unexpected de-tainting with hash keys
by sgifford (Prior) on Jul 11, 2003 at 01:59 UTC
    You're right, this conflicts with what my copy of Programming Perl (2nd ed.) says, on page 358:
    The only way to bypass the tainting mechanism is by referencing subpattern variables set by an earlier regular expression match.
    and with the perlsec manpage:
    The only way to bypass the tainting mechanism is by referenc­ing subpatterns from a regular expression match.
    And I see the same behavior on my system (which is also Perl 5.6.1 on RedHat Linux 7.x (7.2 instead of 7.1)).
Re: Unexpected de-tainting with hash keys
by bobn (Chaplain) on Jul 11, 2003 at 02:13 UTC

    I'd recommend a bug report, but I did one and never had a response of any sort.

    --Bob Niederman, http://bob-n.com

      I just submitted one.

      -sauoq
      "My two cents aren't worth a dime.";
      

        Please let me know if you receive any response.

        Update: Finally got response on my perlbug report (on an unrelated issue, BTW) on July 14th, 10 days after submission, delayed due to all the perl conferences going on).



        --Bob Niederman, http://bob-n.com