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/