On Tue, Apr 6, 2010 at 11:48 AM, Harry Putnam <rea...@newsguy.com> wrote:
> Shawn H Corey <shawnhco...@gmail.com> writes:
>
>> Yes.  The greatest issue is code injection.  This is especially true
>> for the abbreviated form of the two argument open:
>>
>>   open my $fh, $file or die "could not open $file: $!\n";
>>
>> What if the user gave this as $file?
>>
>>   rm -fr ~
>
> Not to be argumentative here... but maybe I can't see as quickly as
> some what this would do.
>
> I can't really visualize what would happen there... wouldn't the open
> just fail?  Further do we need to prepare for a vastly ridiculous file
> name?

You can get an explanation from `perldoc -f open'.

The syntax maps for the two versions look like this:

  open FILEHANDLE,EXPR
  open FILEHANDLE,MODE,EXPR

To summarize the relevant parts (based on reading it just now, not
experience), open allows you to either open a file, or pipe input or
output to or from a command. If you don't know what the means, refer
to Wikipedia: http://en.wikipedia.org/wiki/Pipe_%28Unix%29.

In the two argument version, to indicate that you're piping input or
output from a command you use a pipe symbol (i.e., '|') at the
beginning or end of the second argument (the expression evaluated as
the filename; or in this case, the command).

  open my $f, 'echo foo |' or die 'Failed to open a pipe from echo.';

I would imagine that is to resemble piping directly on the shell,
where there pipe symbol is also used.

  # Example bash command line.
  # Pipes the STDOUT output from the `echo' program into STDIN of
  # the `less' program.
  echo foo | less

With the three argument version, however, the pipe symbols go in the
second argument, the MODE argument, which means that regardless of
what is passed as the EXPR argument it will always be interpreted as
you expect (either a file or a command, depending on what you specify
in the MODE argument).

Imagine that $foo is 'rm -fR ~ |'.

  # If $foo is 'rm -fR ~ |' (from the user) then this invocation:
  open my $f, $foo or die "Failed to open '$foo'.";

  # If equivalent to this one. The die might as well read,
  # "Failed to remove your entire home directory."
  open my $f, 'rm -fR ~ |' or die "Failed to open 'rm -fR ~ |'.";

  # Compare that to the three argument version.
  open my $f, '<', $foo or die "Failed to open '$foo'.";

  # Assuming $foo is again 'rm -fR ~ |', it's still harmless.
  # The '<' MODE guarantees that we're opening a file for reading.
  open my $f, '<', 'rm -fR ~ |' or die "Failed to open 'rm -fR ~ |'.";

In the last example, we're literally trying to open a file named 'rm
-fR ~ |', which BTW is possible on at least some platforms. On Linux,
for example, you can prove this with a simple command.

  touch 'rm -fR ~ |'

The single quotes are necessary to prevent the '~' and '|' characters
from being interpreted by the shell. Essentially, you can never trust
the user when writing programs and always have to assume there will be
malicious users trying to do bad things. You always want to do
everything in your power to prevent this. In the case of open, that
means making sure the program always opens a file and never runs a
command, regardless of what the EXPR argument is.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to