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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.