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

I have a hash stored as a Data::Dumper file. When I try to eval this file into my program to rebuild the hash, I am running afoul of the taint checker. "Insecure dependency in eval while running with -T switch at line .... <USRHASH> chunk 1." The string being evaled to recreate the hash can be any length, so I can't do "standard" de-tainting by substr out the individual fields. The Code looks like:
open(USRHASH,"<$usrhash") or die ......; flock(USRHASH, LOCK_SH) or die..........; $/=undef; eval <USRHASH>; close (USRHASH); $/="\n"; my %newhash=%$USRLST1; # the reference as created by Data::Dumper
I am hoping someone out there has "laundered" an eval somehow. TIA. gassho "I don't believe in an afterlife, but I am taking a change of underwear." ---Woody Allen

Replies are listed 'Best First'.
Re: Laundering tainted 'eval'
by samtregar (Abbot) on May 10, 2002 at 17:08 UTC
    You might consider using Storable instead of Data::Dumper. Storable doesn't require you to eval() to restore your saved data and it's faster.

    -sam

Re: Laundering tainted 'eval'
by dsheroh (Monsignor) on May 10, 2002 at 16:31 UTC
    Taint won't let you feed data from a filehandle directly into an eval because that filehandle could feed you anything, including something terribly destructive. You have to read the file contents into a scalar and untaint it before it can be evaled, like so:
    #!/usr/bin/perl -wT use strict; open (DATA, "<foo.txt") || die; while (my $dataline = <DATA>) { $dataline =~ /(print '[^']*';)/ || next; eval $1; print "\n"; }
Re: Laundering tainted 'eval'
by Mr. Muskrat (Canon) on May 10, 2002 at 17:06 UTC

    Why read the file and eval when you can do it?

    do $usrhash or die "Can't recreate user hash: $! $@"; my %newhash=%$USRLST1;
    The Camel 3 taught me that. Now if I could just remember everything else in there I'd be a great perl programmer.

    Update: Witty reply replaces boring 'Try this:', Mr. Muskrat 2002-05-10 1423 (GMT -0600)


    Who says that programmers can't work in the Marketing Department?
    Or is that who says that Marketing people can't program?

      But <samp>do EXPR</samp> is an eval! The docs say:

      do 'stat.pl';
      is just like
      scalar eval `cat stat.pl`;
      ...
      It goes on to list some differences.

      The point about taint mode is not letting your program execute (some, not all!) potentially dangerous operations. Replacing an eval with do doesn't do that...

        I never said it wasn't...
        only why read the file and eval when you can just do it.
        You save programming time, it's less lines of code, yadda yadda and it just sounds cooler.

        Who says that programmers can't work in the Marketing Department?
        Or is that who says that Marketing people can't program?
Re: Laundering tainted 'eval'
by simonm (Vicar) on May 10, 2002 at 23:22 UTC
    Untaint your input string and eval it inside a Safe partition:
    $code = <USRHASH>; # Blindly untaint ( $code ) = ( $code =~ m/(.*)/s ); # Safe eval require Safe; $USRLST1 = Safe->new->reval( $code );

    The regex removes the taint from $code, and the Safe->new->reval() ensures that the code can only construct a value and return it, without being able to do file I/O, mess with your internal variables, etc. See Safe for more details.

Re: Laundering tainted 'eval'
by Zaxo (Archbishop) on May 10, 2002 at 16:49 UTC

    Taint mode also dislikes relative file paths since they depend on the PWD environment variable. Use absolute paths.

    Update: Not quite right about PWD, that's not used for relative paths (++ariels), nevertheless absolute paths are worth using for security's sake.

    After Compline,
    Zaxo

Re: Laundering tainted 'eval'
by jehuni (Pilgrim) on May 12, 2002 at 17:56 UTC

    You can also try the untaint method of IO::File:

    use IO::File; my $fh = new IO::File; $fh->open("<$usrhash") or die ......; $fh->untaint(); flock($fh, LOCK_SH) or die..........; $/=undef; eval <$fh>; $fh->close(); $/="\n"; my %newhash=%$USRLST1; # the reference as created by Data::Dumper

    Of course, this bypasses the protection that taint mode offers, so it should only be used with great care.

    -jehuni