Perl の taint モードではパイプオープンが機能しないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/964426

  •  12-09-2019
  •  | 
  •  

質問

私の元のスクリプトは次のとおりです。

my $cmd = "dir";
open (H, "$cmd |");
my @result = <H>;
close (H);
print STDERR @result,"\n";

このスクリプトは正常に動作します。スクリプトに次の行を追加すると、機能しません。

$ENV{"LD_LIBRARY_PATH"} = "/opt/VRTSsfmh/lib";
$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

Perl はパイプオープンが呼び出されたときに何を使用しますか?

次のコードを追加すると問題が修正されました。

if ($^O =~ /Win32/i) 
{
    $ENV{'SystemRoot'} =~ /([A-Z]:(\\[A-Za-z0-9_]+)+)/;
    my $system32_dir = $1."\\system32";
    $ENV{'PATH'} = $system32_dir;
}
役に立ちましたか?

解決

あなたの質問は実際にはテイントモードとは関係ありません。あなたが設定した

$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";

通常、これらのディレクトリは Windows マシンには存在しません。 dir は cmd.exe 内部コマンドであるため、これを実行できるようにするには、それが存在するディレクトリをパスに追加する必要があります。

さて、これを行う方法は、既知の明確な場所にパスを設定するという点と完全に矛盾していることに注意してください。悪意のあるユーザーがこの環境変数を変更して、自分の危険なバージョンの dir.

Windows が必ずしも C:\Windows にインストールされているわけではないため、シェルの組み込み機能に依存している場合、Windows 上でテイントセーフなスクリプトを作成するのは複雑になります。

編集: ベースラインとして使用できる短いテスト プログラムを次に示します。

#!/usr/bin/perl -T

use strict;
use warnings;

$ENV{PATH} = join(';', qw(C:\Windows C:\Windows\System32) );
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

open my $pipe_h, '-|', 'dir'
    or die "Cannot open pipe to dir: $!";

print while <$pipe_h>;

close $pipe_h
    or die "Cannot close pipe to dir: $!";

__END__

C:\Temp> perl -T v.pl

...

2009/05/25  08:58 AM             3,584 zzz.exe
              64 File(s)     32,125,365 bytes
              14 Dir(s)  39,251,894,272 bytes free

基本的に必要なのは、システム管理者がインストール時に許容可能なパスをハードコーディングし、信頼できないユーザーがスクリプトへの書き込み権限を持たないようにすることです。

他のヒント

汚染モードが複雑になります。あなたは本当に perldoc perlsec に読んで理解しなければなりません。あなたの問題は、あなたのパスの最初の文で対処されます>セクションます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top