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

I'm getting 'Insecure dependency in eval while running with -T switch at <------ this eval'.
How do I get rid of it? (besides switching off taint mode)
open (F,$tmplpath.$filename) || die "Cannot open: $tmplpath$filename +: $!"; $tmpl = <F>; close F; $tmpl =~ s/<!--\s*#IF\s*(\(.*?\))\s*-->(.*?)<!--\s*#ELSE\s*-->(.*?)< +!--\s*#ENDIF\s*-->/),($1?qq($2):qq($3)),qq(/gs; #) $tmpl =~ s/<!--\s*#INCLUDE(\(.*?\))\s*-->/),(&{template::gettmplsub( +$1)}(\$c)),qq(/gs; #) # $tmpl =~ s/\$/\\\$/g; # warn eval('qq('.$tmpl.')'); $tmpl = "qq($tmpl)"; my $sub = eval("sub { my \$c = shift; my \@a = ($tmpl); return \\\@a; }"); #<------ this eval


T I M T O W T D I

Replies are listed 'Best First'.
Re: Untainting known good data
by wog (Curate) on Sep 07, 2001 at 02:09 UTC
    If you know you trust your input file you should be able to make all data comeing from the file be trusted. You can do this with IO::Handle's untaint method:

    use IO::Handle; # ... F->untaint == 0 or die "Untainting filehandle failed: $!\n"; # ...

    As the IO::Handle's docs say, this is a very trusting action to take and should only be done if you can really trust what you are untainting.

    You could, of course, take another route of actually untainting the $tmpl variable:

    ($tmpl) = $tmpl =~ /(.*)/s;
Re: Untainting known good data
by chipmunk (Parson) on Sep 07, 2001 at 02:12 UTC
    The perlsec (for security) documentation explains tainting in general and shows how to untaint variables.
Re: Untainting known good data
by runrig (Abbot) on Sep 07, 2001 at 02:24 UTC
    You're sure '$tmp1' is safe? What if it's ' unlink "/etc/passwd"' and you later call the sub? (Ok, so if its Windows, what if its something equally horrible?). What if some evildoer replaces the file you're reading with evil things? Are you sure you want to call eval with quotes instead of block delimiters?

    Update: Ok, I missed the qq, that just makes it a little trickier. What if $tmp1 is '@{[unlink "/"]}' ?

    I don't see the need to call eval anyway, use a closure:

    # I assume this is just an example, as '$c' and '@a' serve # no real purpose here my $sub; { my $tmp = $tmp1; # You could even skip assigning to '$tmp' if '$tmp1' # already 'enclosed' in another limited context $sub = sub { my $c = shift; my @a = ($tmp); return @a; }; }
    More update: I see this doesn't account for eval'ing the substitutions you're making, but I would rethink those also, the way you are 'calling' the 'template::gettmplsub' sub it will not get executed anyway. (Hmm, I guess it will later...)
      Yes, I am sure my file is OK, since it is hardcoded at all points which file is read, and if anyone but me has access to the files anyway, the damage is already done...

      'template::gettmplsub' sub it will not get executed anyway
      Which is EXACLY the point ;) It is MUCH cheaper to eval it into a sub than eval it every time you need the string in the file... (Benchmark reports about 2000% speed increase)

      T I M T O W T D I
Re: Untainting known good data
by Beatnik (Parson) on Sep 07, 2001 at 14:47 UTC
Re: Untainting known good data
by runrig (Abbot) on Sep 07, 2001 at 04:13 UTC
    Why not use Template-Toolkit or some other templating module, which this more or less seems to be emulating?
Re: Untainting known good data
by Cine (Friar) on Sep 07, 2001 at 02:08 UTC
    And without resorting to Inline C...
    use Inline C => qw(void I_TRUST_THIS(SV* a){SvTAINTED_off(a);}); ... I_TRUST_THIS($tmpl);


    T I M T O W T D I