Perl Perl_2
Perl 「 モジュール 」 CGI 実用的なファイルアップロード 13 汚染チェックの正規表現 (0x11a)

目次 - Perl Index
Theme
Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x11a 回。
CGI.pm で、実用的なファイルアップロードの処理を確認する。その 13 回。実際のアップロードの処理を請け負うサブルーチンの中から、利用を「 許可する文字列 」を表した正規表現の意味を確認する。
ファイル名の文字列チェック
前回 (0x119) に引き続き、実用的なファイルアップロードの処理を確認します。
Cgi upload - perlmeme.org で紹介されている、実用的なコードでは、サブルーチン「 save_fiel() 」の中で次の様な文字列の汚染 ( taint ) チェックを行っています。これは「 許可する文字列 」を表した正規表現です。
if ($filename =~ /^([-\@:\/\\\w.]+)$/) {
$untainted_filename = $1;
} else {
die <<"EOT";
Unsupported characters in the filename "$filename".
Your filename may only contain alphabetic characters and numbers,
and the characters '_', '-', '\@', '/', '\\' and '.'
EOT
}
この例で許可しているファイル名は「 /^([-\@:\/\\\w.])+$/ 」のパターンのみです。このパターンの意味するところを、個別に確認します。
正規表現「 / / 」
許可された文字列パターンの正規表現を確認します。
まず、マッチングパターンを囲む「 / / 」は、単純なパターンマッチングを行う際に利用する「 m// 」演算子のデリミタです。(0x62) で確認した通り、デリミタを「 / 」とする限り、冒頭の「 m 」は省略可能です。
正規表現「 ^ 」「 $ 」
マッチングパターンの先頭と末尾に置かれた「 ^ 」と「 $ 」は、行の先頭と末尾を表す「 ワードアンカー 」です。
このワードアンカーは (0x67) で確認済みですが、現在は、より意図が明確な「 \A 」と「 \Z 」、および「 \z 」の利用が推奨されています。これらは、 (0x68) で確認しました。
正規表現「 ( ) 」
行頭と行末を除くマッチングパターンを囲む「 ( ) 」は、文字列の「 グループ化 」と「 キャプチャ 」の機能を提供します。
今回のケースでは、条件式が 真 であった場合の処理として次の処理を行っていることから、「 キャプチャ 」機能を利用していることが分かります。変数「 $1 」は、キャプチャした文字列を参照できる特別なスカラ変数です。
$untainted_filename = $1;
パターンのキャプチャとその参照方法は、(0x5d) で確認しました。
正規表現「 [ ] 」
「 ( ) 」の内側でマッチングパターンを囲む「 [ ] 」は、内側のパターンを 1 つのクラス ( 文字クラス ) として扱う機能を提供します。
この機能は、文字クラスの各文字いずれか 1 文字にマッチングすれば 真 を返します。今回の例で言えば、「 - 」「 \@ 」「 : 」「 \/ 」「 \\ 」「 \w 」「 . 」のいずれかにマッチングします。
「 - 」は、文字クラスの中では範囲を表す意味を持ちますが、クラスの先頭に配置されていることから通常の文字として認識されているはずです。
Perl 正規表現の各文字クラスは (0x5f) 等で確認しました。
正規表現「 -\@:\/\\\w. 」
マッチングパターン中の各文字を確認します。
マッチングパターンの各文字は「 - 」「 \@ 」「 : 」「 \/ 」「 \\ 」「 \w 」「 . 」ですが、 ここで留意すべきは、「 \ 」( back slash ) がメタキャラクタ ( 特別な意味を持つ文字 ) の効果を打ち消すメタキャラクタであることです。
つまり、実際には、「 - 」「 @ 」「 : 」「 / 」「 \ 」の記号が許可されるということです。バックスラッシュによるメタキャラクタの効果打ち消し機能は (0x59) で確認しました。
残りの「 \w 」は、任意の単語/文字 ( 通常 ASCII コードのみ ) にマッチングする文字クラスです。これは (0x61) で確認しました。
「 . 」は、(0x5b) で確認した (改行以外の) 任意の 1 文字にマッチングするメタキャラクタですが、(0x5f) - "文字クラスの中の記号" で確認した様に、「 [ ] 」クラスの中ではその効果を消失するため、ここでは単に「 ピリオド 」( period ) の文字としてのみ機能します。
正規表現「 + 」
最後に残った「 + 」は、(0x5b) で確認した量指定子です。
「 + 」は、直ぐ左にある文字の 1 回以上の繰り返しにマッチングするので、ここでは、文字クラス「 -\@:\/\\\w. 」いずれかの繰り返しに対応します。つまり、クラス内の文字を組み合わせた文字の列を表すことが出来ます。
不許可文字を含む場合の処理
if 文の条件式で指定された正規表現のマッチングパターン「 /^([-\@:\/\\\w.]+)$/ 」は、上記で確認した通り、文字列の初めから終わりまでが「 [-\@:\/\\\w.]+ 」のみで構成されたファイル名のみを 真 と判定します。
この条件から外れたファイル名が指定されていた場合は、次の処理を行ってプログラムを終了します。
} else {
die <<"EOT";
Unsupported characters in the filename "$filename".
Your filename may only contain alphabetic characters and numbers,
and the characters '_', '-', '\@', '/', '\\' and '.'
EOT
}
この処理は、(0x48) で確認した関数「 die 」とヒアドキュメントを利用しています。
関数「 die 」は、意図的に致命的なエラー ( 例外 ) を発生させてプログラムを終了させるので、不許可文字列を含むファイル名をもったファイルはアップロード出来ません。
ユーザに提示するメッセージは次のもので、エラーになった理由と、利用可能な記号を説明しています。
Unsupported characters in the filename "$filename". Your filename may only contain alphabetic characters and numbers, and the characters '_', '-', '\@', '/', '\\' and '.'
( サポートしていない文字があります ファイル名 $filename の中に. あなたのファイル名には アルファベット文字と数字, それと 文字 '_', '-', '@', '/', '\' および '.' のみ含むことが出来ます。)
0x11a -> 0x11b へ
次回は、もうひとつの汚染チェックの内容を確認します。
参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。
目次 - Perl Index
Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)