本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはcharsbarこと石垣憲一さんで、
Perl 5.26リリース
去る2017年5月30日にPerl 5.
Perl 5はかれこれ20年以上も同じメジャーバージョンを使い続けていることからも察せられるように、
Perl 5.
本稿では、@INCからカレントディレクトリが削除された経緯とその対策を説明し、
@INCからカレントディレクトリが削除
Perlはバージョン3の時代である1990年から、@INCの末尾に、jcode.というライブラリがよく利用されましたが、jcode.というファイルを設置するだけで期待したとおりに動作したのは、@INCの末尾にカレントディレクトリが含まれていたからです。
# ほかの場所にインストールされていなければ
# CGIスクリプトと同じディレクトリにある
# jcode.plを読み込む
require "jcode.pl";Perl 5.@INCから.が削除されました。上のコードはそのままではもう期待どおりの動作はしません
何が問題だったのか
UNIX系OSの世界、
読み込んだ時点でなにがしかのコードが実行されてしまうという点では、
Rubyの対応とPerlの初期の反応
そのため、$:)
Perlの世界でも、@INCからカレントディレクトリを削除する提案がされていたほか、
CVE-2016-1238とPerlの対応
この議論は2016年4月にまたも蒸し返されるのですが、
対策を取れば既存のモジュールやアプリケーションが壊れることはこれまでの議論からもわかっていたので、
公式にはCVE-2016-1238というIDで識別されるこの脆弱性に関する議論は1年近く続きました。その詳細は割愛しますが、@INCからカレントディレクトリが削られました。コアモジュールのうち特によく使われるものについては、do関数については、
どのように対応すればよいのか
この変更によって、Catalystのように多くの利用実績があるWebアプリケーションフレームワークなども含まれているため、
どのように対応すればよいかは立場によって変わりますが、
ツールチェインを更新する
一般的なCPANモジュールについては、
最近新たにPerl 5.Test::Harnessモジュールを最新のものにしてください。
CPANクライアントとしてcpanmコマンドを使っている人は、
$ cpanm App::cpanminus Test::Harnessまた、Minillaなどのモジュールオーサリングツールを使っている場合も、
環境変数を設定する
CPANクライアントを最新のものに更新するだけでインストール時の問題が解決するのは、PERL_という環境変数を設定して、@INCの末尾にカレントディレクトリを追加させているためです。
この環境変数はあくまでも一時しのぎで、
$ export PERL_USE_UNSAFE_INC=1適切な検索パスを指定する
CPANモジュールのようにほかのユーザーにインストールして使ってもらうモジュールやアプリケーションを開発している人は、
もっとも、libディレクトリの下にまとめられているモジュールやアプリケーション自体がこの問題の影響で挙動を変えることはめったにありません。問題となるのはたいてい、Makefile.やBuild.、
これらの中でinc::Module::Installやt::Testのようなディレクトリ名を含むモジュールを利用している場合は、@INCの中にカレントディレクトリが含まれていることが前提となっているため、
従来どおりの挙動にしたい場合は、Makefile.やテストファイルの先頭で、@INCの末尾にカレントディレクトリを追加してください。
# 末尾にデフォルトのカレントディレクトリがなければ追加
BEGIN { push @INC, "." if $INC[-1] ne "."; }上記で条件節を追加しているのは、
CPANディストリビューションの場合、libモジュールを使ってカレントディレクトリを追加してもよいでしょう。
use lib ".";ただし、libモジュールは@INCの先頭にカレントディレクトリを追加するため、FindBinモジュールや__キーワードなどを利用して、@INCには相対パスを含めないようにしたほうがよいでしょう。
use FindBin;
use lib $FindBin::Bin;別のツールに切り替える
場合によっては、
たとえば、Module::Installについては、Minillaなどのオーサリングツールに移行するか、ExtUtils::MakeMakerやExtUtils::MakeMaker::CPANfileなどのモジュールを使うことも検討してください。
doやrequireでライブラリを読み込んでいる場合
古くからあるCGIスクリプトなどでrequire関数を使ってカレントディレクトリにあるライブラリを読み込ませている場合は、
require "./jcode.pl";アプリケーションの設定をdo関数で読み込ませている場合も同じです。
do "./config.pl";もちろん./の代わりに$FindBin::Binなどでパスを指定してもかまいません。
doの新しい警告
doはuseやrequireと違ってファイルが見つからなくてもエラー終了しないため、@INCの変更でカレントディレクトリのファイルが見つからなくなっても気付けません。そのため、
do "config.pl" failed, '.' is no longer in @INC;
did you mean do "./config.pl"?古いPerl向けの対応
ここまではPerl 5.
OSによっては古いバージョンのPerlにこの変更をバックポートしているものがありますが、
簡単に対応可能なPerlかどうかを調べるには、-Vオプションは、
$ perl -V:usesitecustomize
usesitecustomize='define';defineの値が返ってきたら対応できます。
続いてもう一つPerlの設定を調べます。
$ perl -V:sitelib
sitelib='/usr/local/share/perl5';表示されたディレクトリの下にsitecustomize.というファイルがなければ作成し、
if (!$ENV{PERL_USE_UNSAFE_INC}) {
pop @INC if $INC[-1] eq ".";
}これでperl -Vを実行すると、@INCから.が消えたことが確認できるはずです
独自のコマンドをインストールする場合
独自のコマンドをインストールするCPANディストリビューションについては、@INCからカレントディレクトリを抜くようにしたほうがよいでしょう。
典型的にはコマンドの先頭付近に先ほどと同じような行を追加します。
BEGIN { pop @INC if $INC[-1] eq "."; }なお、@INCの調整は起動に使われるスクリプトの先頭で一度行えば十分です。Perlに同梱されるコアモジュールの中には、@INCをローカライズしてカレントディレクトリを省いているものもありますが、
<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT

