9.2. Perl

Perl プログラマは、まず perlsec(1)を読んだ方が良いでしょう。この man には 安全が求められる Perl プログラムの書き方に関して、課題がたくさん載っています。 特に perlsec(1)では、「汚染(taint)」モードについて説明しています。安全性が 必要なプログラムは、このモードを使用すべきです。 実もしくは実効ユーザ id やグループ id が違っていれば、自動的に汚染モードが有効 になります。もしくは、-T をコマンドラインに指定して有効にできます(たとえば CGI スクリプトのように、誰かの代わりに実行するなら、後者を使ってください)。 汚染モードは、さまざまなチェックを有効にします。たとえば、ディレクトリのパス のチェックをして、他のユーザが書き込めないようになっているかをチェックします。

しかし、汚染モードの効果が最もはっきり現れるのは、誤ってプログラム外の何か に影響を与えてしまわないように、プログラム外部からくるデータを使わない方が 良い場合です。 汚染モードでは、外部から得た入力は「汚染された」ものとして印が付けられます。 外部からの入力には、コマンドラインの引数や環境変数、ロカール情報(perllocale(1) 参照)、システムコールの結果(readdir や readlink、getpw* の gecos フィールドの 呼出し)、ファイル入力すべてがこれに該当します。 汚染されたデータは直接利用されません。また、間接的にサブシェルから呼び出す コマンドも利用しません。ファイルやディレクトリ、プロセスを修正するコマンド でも利用しません。 重要な例外が 1 つあります。引数リストを system もしくは exec に渡す場合、 リスト要素には汚染度チェックが働きません。したがって、汚染モードでの system や exec には特に注意を払ってください。

汚染されたデータから派生したデータ値はどれも汚れています。 例外が 1 つあります。データをきれいするには、汚染されたデータの部分 文字列を抜き出します。 ただ、部分文字列としてむやみに「.*」を使わないようにしてください。 汚染を防ぐ仕組みを台無しにしてしまいます。 そのかわりに、プログラムが許容する「安全な」パタンを識別するパタンを 使って、「有効な」値を取り出して下さい。 値を取り出した後も、その値をチェックする必要があります(特に長さ)。

open や glob、backtick 関数はシェルを呼んで、ファイル名に含まれるワイルド カード文字を展開します。これがセキュリティホールを開けるのによく使われます。 これらの関数をまったく止めるようにするか、perlsec(1)にあるように、より 特権を少なくした「サンドボックス」を使用するようにしてください。 特に backtick については、system()を呼び出すように書き直してください(もしく は完全に書き直して、より安全なものに変更してください)。

率直に言えば、Perl の open()関数は、安全が求められるプログラムにとっては 「何でそうなるのかな?」状態です。open()はテキストを解釈しますが、念入りに フィルタをかけないと、セキュリティ上の問題がたくさん起こってしまいます。 ファイルをオープンしたり、ロックしたりするコードを書く前に、perlopentut(1) を調べてください。 たいていの場合、sysopen()はファイルをオープンするに当たって、さらに安全な方法 (さらに複雑ですが)を提供しています。 新しい Perl 5.6 では、open() の呼び出しにさらに 3 つのパラメタを用意して、 sysopen()の複雑さを排し、解りにくい動作を無効にしました。

Perl プログラムは警告フラグ(-w)を有効にすべきです。これで潜在的に危険であった り、古臭い式に警告を出せます。

Perl プログラムは、制限をかけた環境でも動かせます。 さらに詳しい情報は、Perl の標準配布物に入っている「Safe」モジュール を見てください。 このモジュールがどの程度監査してくれるか定かではありませんので、これに セキュリティ上の信頼を寄せるのは注意してください。 「Penguin Model for Secure Distributed Internet Scripting」を詳しく 調べてもよいでしょう。このドキュメントを書いている時点では、まだ コードもドキュメントも利用できないようですが。 【訳註:Penguin Model for Secure Distributed Internet Scripting は http://www.hpcf.upr.edu/~humberto/documents/penguin-safe-scripting.html を参照してください】