Perl/CGI

出典: フリー教科書『ウィキブックス(Wikibooks)』
移動: 案内検索

CGI[編集]

PerlでCGIスクリプトを書く場合はCGIモジュールを使うことが一般的である。まずは簡単なサンプルから。

#!/usr/bin/perl
 
use strict;
use warnings;
 
use CGI;
 
my $q = new CGI;
print $q->header(-type=>'text/plain', -charset=>'utf-8');
print "Hello world!";

CGIモジュールのheaderメソッドはHTTPレスポンスヘッダを生成するメソッドである。「-type」でContent-Typeヘッダフィールドの値を指定する。また、「-charset」に文字符号化方式を指定すれば、Content-Typeヘッダフィールドの値にcharsetを付与することができる。

クエリ文字列を解析しパラメータを取り出すには、paramメソッドを使う。

use CGI;
my $q = CGI->new;
my $title = $q->param('title'); # ?title=Perl/CGI ならば "Perl/CGI" を返す

paramメソッドにはパラメータ名を渡す。引数なしで呼び出すと、すべてのパラメータ名と値のペアをリストとして返す。

use CGI;
my $q = CGI->new;
my %param = $q->param();
print $param{title};

このように、CGIモジュールを使うことで、CGIスクリプトに必要な処理を簡略化して記述することができる。

CGI::Carp[編集]

CGIスクリプトでエラーが発生した場合、サーバの設定によってはエラーログにエラーの内容が記載されるが、CGI::Carpモジュールを使うとウェブページ上にエラーメッセージを出力することができる。

use CGI::Carp qw(fatalsToBrowser);

fatalsToBrowserをインポートすると、致命的エラーが発生した場合にエラーメッセージを出力する。これにより、CGIスクリプトのデバッグが容易になる。

warningsToBrowserを呼び出すと、致命的でない警告メッセージをHTMLのコメントとして出力することができる。

use warnings;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
warningsToBrowser(1);

CGI::Carpはdieやwarnをラップし、それらが呼び出されたときにエラーメッセージをHTMLとして出力する仕組みになっている。モジュール内ではCarp、CGIスクリプト内ではCGI::Carpを使うことが推奨される場合がある。

-Tスイッチ[編集]

CGIスクリプトでは外部からデータを渡されることが多いが、それらのデータをチェックせずに出力するなどしてクロスサイトスクリプティングなどの脆弱性を生む危険性がある。

perlに-Tスイッチを付けると、taintモードが有効となり、外部から渡された安全性が疑わしいデータを「汚染」されているものと見なす。汚染されたデータを加工せずに出力しようとすると、例外を発生させてスクリプトの動作を中断する。

#!/usr/local/bin/perl -T
use CGI;
my $q = CGI->new;
my $text = $q->param('text'); # $textは汚染されている
my $copy = $text; # $copyは汚染されている
$copy =~ s/&/&/g; # $copyは浄化された
print $copy; # OK

-Tスイッチは脆弱性を完全に防げるものではない。上記のコードでは、例えばMIMEタイプがtext/htmlの場合、<や>などのHTMLの構文に使われる文字をエスケープする処理を$copyに施していないため、任意の構文を埋め込むことが可能になってしまう。

このように万全ではないものの、汚染されたデータの使用を抑制することはできるため、外部からデータを受け取るCGIスクリプトでは常に-Tスイッチを有効にすることが推奨される。