The 2-argument open function is insecure, because the filename can include the mode. If it is not properly validated, then files can be modified, truncated or in the case of a pipe character, run an external command.

$file = "| echo Aha";
open my $fh, $file;       # <-- THIS IS BAD

This will execute the command embedded in $file.

Even when the filename is generated by your code, you can run into unexpected edge cases. For example, in a Unix shell run the command

touch '| echo Aha'

and in the same directory run the script

opendir( my $dh, ".");
while ( my $file = readdir $dh ) {
    next if -d $file;
    open my $fh, $file;   # <-- THIS IS BAD
    close $fh;
}

This is more subtle, and will execute the command embedded in that filename.

It is the same bug in File::Find::Rule that became CVE-2011-10007. (If you haven’t already upgraded File::Find::Rule to version 0.35 or later, please do so. That module has more than 1,700 direct or indirect dependents.)

The SEI CERT Perl Coding Standard recommends against using the two-argument form of open().

The fix is simply to use a 3-argument form, where the second argument is the mode and the third is the filename:

open my $fh, '<', $file;

The 3-argument open has been supported since Perl v5.6.0, so there is no worry about supporting older versions of Perl.

You can identify this issue in your code using the Perl::Critic ProhibitTwoArgOpen policy. There is a similar policy in Perl::Lint.