で、ここまで調べてみて、思ったんだけど、Taint mode は安全では無い値の利用について、その値を利用する (すなわち、出力する) 際の水際で、状況に応じたチェックを行い、安全かどうかを検証する。これが意味するところは、すなわち、プログラマーが状況ごとに正しい値の形式を把握していなければ、Taint mode を利用する意味はあんまりなくなっちゃうんじゃないか? っていうこと。
何が言いたいのかっていうと、つい最近、おいらはこんな記事を書いた。驚くべきことに、taint mode
でぐぐると、この記事は結構上位に表示されちゃう。で、この中でおいらは、以下のように書いてしまったわけなんだけれども、
で、実際の、(恐らく) 正しい (と思われる) 運用方法ってのは、一通りシステムを作り終えた段階で最終チェック的なテストの一つとして、あるいはある程度組み終えたところで設計の正当性を確認する目的で、んー、どっちかっていうと後者の意味合いの方が重要になってくるのかな、とにかくそんなタイミングで Taint mode を ON にしてみて、動くことをチェックする。それだけ。で、そこで動かなかった場合に、原因と、それに起因する設計上の欠陥を調査し、設計上の semantics を考慮したうえで、修正を反映する。つまり、Taint なデータが流れている場所を見つけたからといって、その場所だけを局所的に直すんではなくて、それを元に (というかヒントの一つ、ぐらいの目安で) 設計自体を見直す、っていう使い方ができれば、いいんでないかなぁとか思うわけです。
実際に、「結果として危険な値」を流すことができなければ、つまりそういうケースを検証するテストデータを用意することができなければ、設計上の欠陥を見つけることもできないのではないか? ついでに言えば、優秀なテスト設計者がテストを作ってくれるならともかくとしても、仮に設計者自らがテストデータを作成するんであれば、危険な値が流れる可能性のあるデータを用意できるという時点で、プログラムの設計上のキーポイントを把握していると言うことでもあるわけで、そう考えると、上記のような目的で Taint mode を利用するってのは、実はナンセンスなんじゃないかと思えてきてしまったのです。
そうすると、やっぱり Taint mode の正しい使い方は、本番環境で使用する、なのかなぁ。なんだろうなぁ。
あ、ちなみに、推奨されるべき実装は、そもそも 2引数形式の open
は使用せず、3引数形式の open
を使用するか、または sysopen
を使用する、なのであったりします。
#!/usr/bin/perl -T use strict; my $file = $ARGV[0]; open FH, '<', $file; # そもそも 3引数形式を使えと
# いちおうこいつにもリンクしとこ。。。
かなだまさかつさん、コメントにてご指摘ありがとうございます。
追試してみました。
#!/usr/bin/perl -T use strict; my $file = $ARGV[0]; open FH, '>', $file;
3 引数 open
を書き込みモードで呼び出す場合、上記では当然例外になります。これは、以下のような呼び出しであっても例外になります。
murachi@maha ~ $ ./taint.pl hoge.txt Insecure dependency in open while running with -T switch at ./taint.pl line 5. murachi@maha ~ $
んで、じゃあサニタイズしましょーってな感じで (←こらこら)
#!/usr/bin/perl -T use strict; my $file = $ARGV[0]; $file =~ s/\W/_/g; # ←とりあえず置換してみた open FH, '>', $file;
とかやっても、まだ値は「危険」と看做されて例外が発生します。これがかなだまさかつさん曰くところの、
セコメントをする