春を迎えて暖かい日が増えてきましたが,次のマイナーバージョンであるPHP 8.2の開発も少しずつ進んでいます. PHP開発用メーリングリスト(php-internals)では,新しい機能に関する議論が行われており,PHP-RFCで新しい機能の提案および投票が行われています.
一方,2月18日に比較的影響度が大きいセキュリティ関連のPHPのリリースが行われました.本稿では,セキュリティ関連修正リリースの情報とPHP 8.2に向けて提案されている機能の紹介を行います.
PHP8の最新版であるPHP 8.1.0が11月25日に正式リリースされた後,PHPの開発陣は次のマイナーバージョンであるPHP 8.2の開発を開始しました.本稿では,PHP 8.2における現時点での変更点を含むPHP関連の最新の状況について紹介します.CVE-2021-21708
Filter_validate_float関数とmin/max limitを用いた際,フィルタが失敗すると
開放後のメモリを使用してしまうuse after freeが発生し,リモートコード実行の脆弱性が発生します.
フィルタ機能に関するセキュリティ脆弱性により修正版リリース
PHPの全てのリリースに共通する比較的影響度が大きいセキュリティ脆弱性が発見され,2月18日にそれぞれ PHP 7.4,8.0,8.1に関する修正版としてPHP 7.4.28,8.0.16,8.1.3がリリースされました.すべてのPHPユーザは,修正後のバージョンへの早期の更新が推奨されます.なお,PHP 7.4はすでに通常のバグ修正期間は終了しており,セキュリティ修正のみが行われる期間となっています.関連して,各ディストリビューションから同様の修正が適用された版がリリースされる可能性があります.
なお,本修正はPHP 7.4以降で導入された機能(float用フィルタへの最小値・最大値指定)に関連するバグであり,PHP 7.3以前のバージョンには影響しないものと思われます.ただし,PHP 7.3および以前のバージョンはすでにセキュリティ関連の修正も含めてサポートが終了しています.該当するサポート対象外のPHPのバージョンを使用するユーザはより新しいサポート中のバージョンへの更新が推奨されます.
本件の脆弱性が関連するコードの例を以下に示します.
filter_var($input,FILTER_VALIDATE_FLOAT,
["options" => ['min_range' => -1, 'max_range' => 1]]);
filter_var()関数は,ユーザから入力された変数の内容を指定した変数の種別でフィルタリングするためのもので,ユーザ入力値の確認のために利用されています.今回の脆弱性はfloatの判定を行うFILTER_VALIDATE_FLOATを指定し,かつ,範囲を指定するオプション(min_range,max_range)を指定した場合に発生します.上記の例では,-1~+1の範囲内にあることを確認していますが,この際,変数$inputにチェック範囲外の値(例えば”+11”)が入っていると,棄却処理に入ります.しかし,この際のメモリ開放の手順に問題があり,確保されたメモリが解放された後に利用される状態(use after free)となるため,リモートコード実行などの脆弱性が発生します.
ユーザ入力のフィルタリングを行う機能でセキュリティ関連の脆弱性が発生するのは皮肉ですが,メモリ開放のタイミングがセキュリティ対策としても重要であることを示す例であるといえます.
PHP 8.2の開発スケジュールと体制
次のマイナーバージョンであるPHP 8.2は,従来のリリースサイクルに基づくとすると,本年末にリリースされることになりますが,本稿執筆時点ではリリースに向けたスケジュールやリリースマネージャの選定などは始まっておらず,代表的な変更点やスケジュール等の詳細は未確定の状態です.現時点では,新しい機能の提案や議論が行われている状態ですので,おそらく6月頃にはリリースに向けたスケジュール等が見えてくるものと思われます.以下,PHP に向けて提案されている機能を紹介します.
null型およびfalse型の追加(https://wiki.php.net/rfc/null-false-standalone-types)
本提案は,PHPにnullとfalseを新たな標準型に追加することを提案するものです.現在,PHP 8.2に向けた追加機能として提案段階にあり,採否を問う投票が行われいますが,本稿執筆段階では賛成33,反対0となっており,採用の要件である2/3を上回る賛成多数で採用される見込みです.以下提案内容について説明します.
従来のPHPにおいて,nullは単一の値を保持するユニット型,falseは論理値を保持するリテラル型として扱われています.ユニット型は情報を保持できず,関数などの型宣言に指定することができないという制約があります.
最近のPHPでは,型宣言を使いやすくする拡張が行われており,PHP 8.0では共用型(union),PHP 8.1では交差型(intersection)が導入されています.falseは,共用型の中で指定することができますが,”null | false”のように組み合わせて指定することはできません.
この提案が採用された場合,以下のように関数(メソッド)の引数および戻り値宣言,変数の型宣言にnullおよびfalse型が指定できるようになります.
<?php
function test(null $v): null {
return $v;
}
class Foo {
public false $v = false;
public function foo(false $v): false {
return $v;
}
}
この提案は,最近のPHPで行われている型宣言をより使いやすくする一連の拡張と関連しており,よりPHPを使いやすくする拡張として採用されるものと思われます.
今回は,次のマイナーバージョンアップにあたるPHP 8.2で予定される変更点について紹介しました.冒頭に書いたように,まだ,PHP 8.2の開発は本格化しておらず,今後,RFCにおける機能提案・投票を経て,いくつかの有用な機能が追加されると思われます.次回以降もPHP開発関連の話題を中心に紹介していきたいと思います.