in reply to Insecure dependency in piped open

There are two security related issues: one is a taint issue and the other has to do with not using the multi-argument version of exec to spawn programs.

First the taint problem: the value passed into $host is probably tainted and you are not untainting it. See perldoc perlsec for more info on how to untaint data.

Another security issue is your use of exec() with a single arguement. You should use something like:

open(my $fh, "-|", $NSLOOKUP, "-type=any", $host) or die "unable to exec $NSLOOKUP: $!";
This ensures that $host will not be interpreted by the shell. If you really need to re-direct STDERR, consider using something like IPC::Open3.

Here is a good write-up of the security issues around tainting and calling other processes written by brian_d_foy: Secure Programming Techniques

Replies are listed 'Best First'.
Re^2: Insecure dependency in piped open
by gugubanana (Acolyte) on Jun 29, 2008 at 12:46 UTC
    thanks pc88mxer, for your comments. your right that the $host is tainted and i've fixed the issue. whats more,

    my $fh = new IO::File "$NSLOOKUP -type=any $host 2>&1 |";

    is same as

    open(my $fh, "-|", $NSLOOKUP, "-type=any", $host)
    however only difference from the two is that yours is more optimised than mine. so i've decided to use yours.

    if your have more ideas of improvement or security issues please let me know.

    many thanks
      Actually those two are subtly different. One of them has a single string, and Perl will hand that string to the shell to parse. If $host contains any special shell characters, the shell will interpret them; for example if $host was set to:
      www.google.com; rm /path/to/your/script
      the shell will see something like:
      /bin/nslookup -type=any www.google.com; rm /path/to/your/script 2>&1 | +";
      and will go ahead and try to remove your script, if it has permission. That is why Perl won't let you do it with taint mode on.

      The multi-argument piped open doesn't send anything to the shell, and so avoids this problem.

      There is also a difference in where standard error goes. In the first example it will be read from the pipe; in the second it will go to the original program's standard error, perhaps to a Web server error log.

      Finally, for this particular purpose, there is probably a module available on CPAN (like Net::DNS) that will do the work without using an external program at all.

      Good luck!