rdww has asked for the wisdom of the Perl Monks concerning the following question:

I build the following format in a setuid script with a function I call BuildFormat. The last statement then returns this as a string. When I call eval(BuildFormat()) to cause the format to be defined I get the following error message

Insecure dependency in eval while runing setuid at /dev/fd/3 line 275

I need to build & rebuild this format on the fly several times though out the life of the program. Any suggestions on how to get around?

format STDOUT_TOP = SID SERIAL# USERNAME OSUSER MACHINE PROGRAM PR +OCESS STATUS SPID ---- -------- --------- ------- ----------- ----------------------- -- +------ --------- ------ . format STDOUT = @<<< @<<<<<<< @<<<<<<<< @<<<<<< @<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @< +<<<<<< @<<<<<<<< @<<<<< $cols[0], $cols[1], $cols[2], $cols[3], $cols[4], $cols[5], $cols[6], +$cols[7], $cols[8] .
Thanks Robert Walkup

Replies are listed 'Best First'.
Re: setuid script returning Insecure dependency
by tachyon (Chancellor) on Dec 25, 2002 at 10:26 UTC

    When -T taint mode is active Perl stops your code from doing potentially bad things. What this means is that you may not use external input to your script to effect anything outside your script. Without seeing your code all I can suggest is that your @cols array takes a feed from outside the script and is then being used to do something that taint regards as risky. To fix the problem you need to cleanse the values in @cols by running them through a regex like:

    sub untaint { my $val = shift; $val =~ s/[^\w.-]/_/g; # tr/A-Za-z0-9.-/_/c is faster but less e +asy to read for some $val =~ m/([^\w.-])/; my $clean_taint_free_val = $1; return $clean_taint_free_val; }

    In this case we set up a substitution to convert all non alphanumerics . or - to _ and then do a capturing match. The captured value in $1 is untainted as you have processed it and perl assumes you know what you are doing. You modify this as required. It is always better to specifically include what you need adn ditch re rest rather than trying to substitute out potentially risky shell metachars as you will always miss some.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: setuid script returning Insecure dependency
by dws (Chancellor) on Dec 25, 2002 at 04:08 UTC
    I get the following error message ...

    Please show us the code around line 275, including the eval.

      Below is code chunk? line 275 is marked with line ***LINE 275***

      the BuildFormat function is the second function which is called

      Thanks Robert Walkup

      sub PrintToStdOut{ $utlp->LogFile ("FUNCTION=PrintToStdOut\n") if($DEBUG); my($msg,@list)=@_; if(scalar(@list)){ my(@flist); ***LINE 275*** eval($utlp->BuildFormat($fields,"STDOUT",0,\@titles,\@l +engths)); $- = 0; $^L="\n"; if(scalar(@list)){ print STDOUT ("$msg"); if(scalar(@{$list[0]}) > 1){ #if >1 then it is + a multi array @flist=@list; } else{ #is it is a array push @flist,[ @list ]; } for my $ref (@flist){ @cols = @$ref; write STDOUT; } } } else{ print STDOUT ("$msg"); } } sub BuildFormat{ my $self = shift; my($fld_cnt,$fmt,$ext,$titles,$lengths)=@_; $self->LogFile ("FUNCTION=BuildFormat\n") if($self->{DEBUG}); $ext=0 if(!$ext); my(@titles)=@$titles; my(@lengths)=@$lengths; my($format_top) = "format ${fmt}_TOP =\n"; my($format) ="format $fmt =\n"; my($fmtStr); my($colStr); my($headerStr); my($lines); my($i); for ($i=0;$i<$fld_cnt;$i++){ my $strLen=$lengths[$i]; my $tmp=$strLen; $strLen=length($titles[$i]) if(length($titles[$i])>$st +rLen); $strLen=$strLen+$ext; $headerStr="$headerStr" . " " if($i); $lines="$lines" . " " if($i); $fmtStr="$fmtStr" . " " if($i); $colStr="$colStr" . " " if($i); $colStr="$colStr" . $self->rpad('@',$strLen+1,'<'); $headerStr="$headerStr" . $self->rpad($titles[$i],$str +Len+1); $lines="$lines" . $self->rpad("-",$strLen+1,"-"); $fmtStr="$fmtStr" . "\$cols[$i]"; $fmtStr="$fmtStr," if($i < $fld_cnt-1); } $format_top="$format_top" . "$headerStr\n" . "$lines\n" . ".\ +n\n"; $format="$format" . "$colStr\n" . "$fmtStr" . "\n.\n\n"; $format="$format_top" . "$format"; $self->Log("FORMAT -> $format") if($self->{DEBUG}); print("FORMAT -> $format") if($self->{DEBUG}); #print STDOUT ("FORMAT -> $format"); return($format); }
        When faced with a strange problem like this, it helps to strip as much out as possible, to try to get to a small example that demonstrates the problem.

        Here's the example I came up with:

        #/usr/bin/perl -T $insecure = $ARGV[0]; eval makeformat($insecure); write; sub makeformat { my($name) = @_; # note: $name is tainted return "format = \n" . "\@<<<<\n" . '$' . $name . "\n" . ".\n" # the returned format string is tainted }
        The implication is that you're constructing one of your format strings using a variable (or variables) that are still tainted.