Re: perlfaq4: expanding variables in strings

[email protected] (Kevin Meltzer)
Newsgroups perl.perlfaq.workers
Message-ID <[email protected]>
On Wed, Mar 12, 2003 at 08:33:47PM +0000, Brian McCauley ([email protected]) said something similar to:
> 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.

So, it doesn't state "suppose you have untrusted data" and then a few
lines later shows the system() example? Looks that way to me.
 
> > 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.

The attacker is going to hard-code 'system "rm -rf /"' into the code? 
 
> > and -T should catch it.
> 
> Aggh!
> 
> You've got the wrong end of the stick.  -T will completely prevent

You keep referring to a stick. I don't have a stick here with me.

> 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).

And again, your example shows a hard coded Bad Thing. I didn't see
anything in the code example where this data is obtained from an
untrusted source, aside the person writing the code. I believe if I
took data from a file saying 'system "rm -rf /"' and tried to run it,
-T would catch it.
 
> > 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.

Sorry, then I won't quote it again.  

> > 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

"typically a file, database, or CGI input" maybe
"and you would content to trust" ?? typo?

>        executable code from that source then you simply make the
>        source untainted.  This is no more or less dangerous than

You would untaint the 'content' or 'data', no? I'd also suggest a "see
perlsec" somewhere in here.

>        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.

I think this is much better. But, I've said my peace, chimmed in,
tossed about $.06 out there :)

Cheers,
Kevin

-- 
[Writing CGI Applications with Perl - http://perlcgi-book.com]
I write the music I like. If other people like it, fine, they can go buy the
albums. And if they don't like it, there's always Michael Jackson for them to
listen to. -- Frank Zappa (about his music from the Yellow Shark)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.