#navi_header|Perl| [[Perl/codepiece/setuid02]] ではコマンドライン引数の汚染除去を試みた。 今回は、ファイルから読み取った値の汚染除去を試みる。 perlsec( http://perldoc.perl.org/perlsec.html )にあるとおり、Taintモードが有効な場合、Perlプログラムの"外部"から取得される変数は基本的に汚染されていると見なされる。perlsecに上げられているものとして以下が汚染されたものと見なされる。 - コマンドライン引数 - ファイルから読み取った値 - サブシェル起動から読み取った値 - 環境変数(%ENV) - readdir(), readlink(), shmread() の値、msgrcv() で取得したメッセージ これらの値を使って以下の操作を行う場合、致命的なエラーが発生する。 - サブシェルに引数として渡して起動する - ファイル・ディレクトリの名前として使用して、ファイル・ディレクトリ操作を行う 但し、Perl5.8.8のperlsecによると、以下の場合はTaintチェックは行われない。 - print, syswrite の引数 - Symbolic methods and symbolic sub references (? ... 調査不足) 以下のコードピースで、ファイルから読み取った値の汚染除去を試みる。 - コードピース(setuserid3.pl) #!/usr/bin/perl -T use strict; use warnings; my $fn = shift or die "usage: $0 conffile\n"; my $re_filename = qr|[0-9A-Za-z_,\-\./]+|; die "$fn is not untained." unless $fn =~ /^($re_filename)$/; $fn = $1; open FH, "<$fn" or die "open failure. $!\n"; # 引数で渡されたファイル(conffile)から、出力先のファイル名を取得する。 # # conffileは、出力先のファイル名が一行で記述されているテキストファイルとする。 # 例: # /tmp/hoge.txt # my $outfile = ; close FH; # remove new line chomp $outfile; $fn = $outfile; # 汚染除去を行う。 die "$fn is not secure." unless $fn =~ /^($re_filename)$/; $fn = $1; open FH, ">$fn" || die "open failure. $!\n"; print FH "$outfile\n"; print FH "REAL_USER_ID(UID) = $<\n"; print FH "EFFECTIVE_USER_ID(EUID) = $>\n"; print FH "REAL_GROUP_ID(GID) = $(\n"; print FH "EFFECTIVE_GROUP_ID(EGID) = $)\n"; close FH; - 実行結果 -- [[Perl/codepiece/setuid02]] とほぼ同様の結果である為、省略。 例えば上記コードピースで、出力ファイル名をキメ打ちにした場合も、正常に終了する。 print FH "$outfile\n"; 上記コードが有るにもかかわらず正常に終了するのは、printが汚染チェックを行わないからである。 #navi_footer|Perl|