This node is intended as a security-consciousness-raising exercise. I recently ran into the following code in a module:
open FILE, "$dest"; my @lines = <FILE>; close FILE;
I was really impressed. In three lines, I count 2 major security holes, one Worst Practice, and one very minor carelessness. (Can you see what they are? Would it help if I told you that $dest came straight out of a CGI parameter? UPDATE: It's only one major security hole, actually.)
Further discussion in case the above doesn't ring bells:
A piped open allows you to open a UNIX pipe to another program and either send data to it or get data from it. (perldoc -f open for full details.) If the command in question were something like "mail the password file to hacker@address.com", that would be bad. The way to resolve this is to run in taint mode (use the -T switch; perldoc perltaint for full details), and to verify that you have good values in your parameters (note: verify that you have good parameters...do not try to weed out bad ones, or you will miss a few).
When you open a file, do it in either of the following ways:
use IO::File; my $file = new IO::File($dest, '<') or die "Oops, couldn't open $dest: $!";
or
open FILE, '<', $dest or die "Oops, couldn't open $dest: $!";
Either of these specifies precisely what mode (in the above examples, read) you want to open the file in), so any special characters in the filepath are not treated as commands.
Double quote interpolation allows you to stuff arbitrary code--not just scalars and arrays--into a double-quoted string and have it run. For more information, perldoc perlref. The way to make this safe is to not put $dest in quotes; they aren't needed.
UPDATE: I'm wrong about the double quote interpolation problem; as Corion pointed out to me in private message, code is only interpolated once. So these print different things:
$a = "@{[print hello]}"; $z = "$a"; # no output $z = "@{[print hello]}"; # output: hello
In reply to Bad code from the trenches by Whitehawke
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |