Taint mode piped open problem

Taint mode piped open problem

am 26.01.2008 23:07:34 von Rohit

Hello All,

I am writing perl script with taint mode. In which I have to parse PS
command output using command line argument process ID. The problem is
when I store this process id in any variable, by using this variable I
am getting error.

$processID = $ARGV[0];

open(PSDATA, "/bin/ps -wwwp $processID |");
while () {
print scalar ;
}
close PSDATA;

I am getting this taint checking error -> "Insecure dependency in
piped open while running with -T switch at GetWidget.pl line 24."

If I replace $processID to any process id like 250, it works fine.

open(PSDATA, "/bin/ps -wwwp 250 |");

I will appreciate any solution for this problem.

Thanks,
Rohit

Re: Taint mode piped open problem

am 27.01.2008 00:13:04 von Gunnar Hjalmarsson

Rohit wrote:
> I am writing perl script with taint mode. In which I have to parse PS
> command output using command line argument process ID. The problem is
> when I store this process id in any variable, by using this variable I
> am getting error.
>
> $processID = $ARGV[0];
>
> open(PSDATA, "/bin/ps -wwwp $processID |");
> while () {
> print scalar ;
> }
> close PSDATA;
>
> I am getting this taint checking error -> "Insecure dependency in
> piped open while running with -T switch at GetWidget.pl line 24."
>
> If I replace $processID to any process id like 250, it works fine.

You need to untaint $processID.

($processID) = $processID =~ /^(\d+)$/;

Please read more about the topic in "perldoc perlsec".

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

Re: Taint mode piped open problem

am 27.01.2008 00:24:30 von Rohit

Thank you very much Gunnar! It works fine now.
And thanks for routing me to proper doc.

On Jan 26, 3:13 pm, Gunnar Hjalmarsson wrote:
> Rohit wrote:
> > I am writing perl script with taint mode. In which I have to parse PS
> > command output using command line argument process ID. The problem is
> > when I store this process id in any variable, by using this variable I
> > am getting error.
>
> > $processID = $ARGV[0];
>
> > open(PSDATA, "/bin/ps -wwwp $processID |");
> > while () {
> > print scalar ;
> > }
> > close PSDATA;
>
> > I am getting this taint checking error -> "Insecure dependency in
> > piped open while running with -T switch at GetWidget.pl line 24."
>
> > If I replace $processID to any process id like 250, it works fine.
>
> You need to untaint $processID.
>
> ($processID) = $processID =~ /^(\d+)$/;
>
> Please read more about the topic in "perldoc perlsec".
>
> --
> Gunnar Hjalmarsson
> Email:http://www.gunnar.cc/cgi-bin/contact.pl

Re: Taint mode piped open problem

am 27.01.2008 00:26:58 von Ben Morrow

Quoth Rohit :
>
> I am writing perl script with taint mode. In which I have to parse PS
> command output using command line argument process ID. The problem is
> when I store this process id in any variable, by using this variable I
> am getting error.
>
> $processID = $ARGV[0];

Do you have

use warnings;
use strict;

at the top of your script? This probably needs to be

my $processID = $ARGV[0];

> open(PSDATA, "/bin/ps -wwwp $processID |");

Check the return value of open.
Use three-or-more arg open, *especially* in scripts where security is an
issue.
Use lexical filehandles.

open(my $PSDATA, '-|', '/bin/ps', '-wwwp', $processID)
or die "can't fork ps: $!";

> while () {
> print scalar ;
> }
> close PSDATA;
>
> I am getting this taint checking error -> "Insecure dependency in
> piped open while running with -T switch at GetWidget.pl line 24."

@ARGV is tainted, since it comes from outside your program. This means
$processID is tainted as well, so you can't pass it directly to ps
without checking it first. With your script as it stood (1-arg open),
someone could have passed an argument of '1; rm -rf /' and caused
serious trouble. With multi-arg open this is not possible, but for all
Perl knows there could be other problems with passing arbitrary data to
ps.

There are two possible solutions: preferable would be to use a module
like Proc::ProcessTable rather than parsing the output of ps(1);
alternatively, you need to untaint $ARGV[0] by extracting data from a
pattern match. Something like

my ($processID) = ($ARGV[0] =~ /^(\d+)$/)
or die "invalid pid: $ARGV[0]";

Read perldoc perlsec, and note that you will also (if you aren't
already) need to explicitly set $ENV{PATH} before taint mode will let
you run anything at all.

> If I replace $processID to any process id like 250, it works fine.
>
> open(PSDATA, "/bin/ps -wwwp 250 |");

This is because a literal constant like '250' is not from outside your
program, so it isn't tainted. (I guess this means you are already
setting $PATH.)

Ben

Re: Taint mode piped open problem

am 27.01.2008 02:34:46 von Rohit

Hi Ben,

Thanks for this great lesson. Using this I will be able to prevent
other problems too in future.

Again thanks a lot!

~Rohit

On Jan 26, 3:26 pm, Ben Morrow wrote:
> Quoth Rohit :
>
>
>
> > I am writing perl script with taint mode. In which I have to parse PS
> > command output using command line argument process ID. The problem is
> > when I store this process id in any variable, by using this variable I
> > am getting error.
>
> > $processID = $ARGV[0];
>
> Do you have
>
> use warnings;
> use strict;
>
> at the top of your script? This probably needs to be
>
> my $processID = $ARGV[0];
>
> > open(PSDATA, "/bin/ps -wwwp $processID |");
>
> Check the return value of open.
> Use three-or-more arg open, *especially* in scripts where security is an
> issue.
> Use lexical filehandles.
>
> open(my $PSDATA, '-|', '/bin/ps', '-wwwp', $processID)
> or die "can't fork ps: $!";
>
> > while () {
> > print scalar ;
> > }
> > close PSDATA;
>
> > I am getting this taint checking error -> "Insecure dependency in
> > piped open while running with -T switch at GetWidget.pl line 24."
>
> @ARGV is tainted, since it comes from outside your program. This means
> $processID is tainted as well, so you can't pass it directly to ps
> without checking it first. With your script as it stood (1-arg open),
> someone could have passed an argument of '1; rm -rf /' and caused
> serious trouble. With multi-arg open this is not possible, but for all
> Perl knows there could be other problems with passing arbitrary data to
> ps.
>
> There are two possible solutions: preferable would be to use a module
> like Proc::ProcessTable rather than parsing the output of ps(1);
> alternatively, you need to untaint $ARGV[0] by extracting data from a
> pattern match. Something like
>
> my ($processID) = ($ARGV[0] =~ /^(\d+)$/)
> or die "invalid pid: $ARGV[0]";
>
> Read perldoc perlsec, and note that you will also (if you aren't
> already) need to explicitly set $ENV{PATH} before taint mode will let
> you run anything at all.
>
> > If I replace $processID to any process id like 250, it works fine.
>
> > open(PSDATA, "/bin/ps -wwwp 250 |");
>
> This is because a literal constant like '250' is not from outside your
> program, so it isn't tainted. (I guess this means you are already
> setting $PATH.)
>
> Ben