note
ikegami
<p><c>print</c> is an innocent bystander here. No string passed to <c>print</c> will cause <c>rm</c> to execute. The <c>`...`</c> operator is being executed while building the string to pass to <c>print</c>. You could remove the <c>print</c> and you would get the same result.
<c>
> perl -Te "print qq{$var{die()}}"
Died at -e line 1.
> perl -Te "qq{$var{die()}}"
Died at -e line 1.
</c>
<p>A <em>string literal</em> (as opposed to a <em>string</em>) is a form of code. In fact, quotes, <c>qq</c> and the other string literal delimiters are listed as operators in [doc://perlop]. Like other operators, the compiler (<c>perl</c> or <c>eval EXPR</c>) is required to convert them and their operands into executable form. String literal are only string literals in the context of source code, and will not get executed unless they are first compiled.
<p>Most string literals result in code that simply returns a constant string ("Hello World!\n") or in code that performs concatenation ("Hello $name!\n"). However, it is well known that string literals can excute arbitrary code using the reference-dereference-array trick you mentioned. There are other ways.
<c>
perl -e "print qq{... @{[ ...arbitrary Perl expr... ]} ...}"
perl -e "print qq{... ${ ...arbitrary Perl expr... } ...}"
perl -e "print qq{... $var{ ...arbitrary Perl expr... } ...}"
perl -e "print qq{... $var[ ...arbitrary Perl expr... ] ...}"
</c>
<p>I wouldn't call this a new security hole, since <c>eval</c> is needed to exploit it.
<p><b>Updated</b> for readability and clarity, but no changes were made to the substance of the post.
564791
564791