Kevin Meltzer <[EMAIL PROTECTED]> writes:

> I'm also, specifically, not convinced this change is the best:
> 
> -    $text =~ s/\$(\w+)/${$1}/g;  # no /e needed
> +    $text = '@{[ system "rm -rf /" ]}'

That should not be seen as a single change.

One bit has been removed.

Unrelated to that, another bit has been inserted.

It's just an artifact that diff sees it as a change.

> Especially, since that is a poor use of system(),

I cannot see how it can be relevant that the fact that something an
attacker may do is poor style.

> and -T should catch it.

Aggh!

You've got the wrong end of the stick.  -T will completely prevent
externally sourced strings from being used in eval().  But this whole
FAQ is about using externally sourced strings in eval().  It doesn't
say so explicitly in the question, but in practice the strings to be
interpolated come from a file or database of message templates.  It
therefore does not make sense to say that -T will protect you.  (And
IIRC DBI doesn't taint by default anyhow).

> So, as Robert said, "People still learn perl poorly, and still write
> things "the old bad way" that needs to be fixed."

I didn't understand the relevance of it then.  I don't understand the
relevance when you repeat it.
 
> Anyways, I wouldn't mind seeing the patch reworked, even if in smaller
> bits at a time to get it "just right".

Personally I'd settle for "a damn sight better than it was" but in
defference to that request here's my latest attempt to incorporate
your suggestions into answer.  I'm not going to express it as a patch
at this stage as that seems to have caused confusion:

       How can I expand/interpolate variables in text strings?

       You can process a string through Perl's interpolation
       engine like this:

           $text = 'this has a $foo in it...\n  ...and a $bar';
           # Assume $text does not contain "\nEND\n"
           chop ( $text = eval "<<END\n$text\nEND\n" );
           die if $@;

       This will not work, and for good reason, if $text is com-
       ing form a tainted source.  For explanation of how $text
       could contain arbitrary Perl code see ``How do I expand
       function calls in a string?'' in this section of the FAQ.

       If $text is coming from a source external to the Perl
       script (typically a file) and you would content to trust
       executable code from that source then you simply make the
       source untainted.  This is no more or less dangerous than
       using "do()".

       If you do not trust the source that much then you can
       limit and launder the parts of the string that are passed
       to eval() something like this:

           $text =~ s/(\$\w+)/$1/eeg; # needed /ee, not /e

       This still gives unrestricted access to your scalar vari-
       ables.  It is often better to use a hash:

           %user_defs = (
               foo  => 23,
               bar  => 19,
           );
           $text =~ s/\$(\w+)/$user_defs{$1}/g;

       For other variations on the theme of text templates see
       the sprintf() function and numerous modules on CPAN.

Reply via email to