FuelPHP 1.6.1 以下へのセキュリティ勧告(脆弱性)
セキュリティ勧告ページ
FuelPHP 本家サイトにセキュリティ勧告(Security Advisories)のページができました。
公開された 2件の脆弱性
そして、1.6.1 以下に影響する脆弱性 2件の情報が公開されました。いずれも、リスクは低とされています。
いずれの報告も、三井物産セキュアディレクションの寺田さんによるものです。
DB quote_identifier() の問題は、1.7/develop で修正済みであり、1.6.1 以前には以下のパッチを当てることで修正できます。
EM Space の問題は、エスケープせずに出力した場合、いくつかのブラウザで問題になるようです。これは、FuelPHP が使用している htmlLawed というライブラリの問題です。
enchantMOON を 2.4.1 にアップデートした
enchantMOON を 2.4.0 にアップデートした
enchantMOON がバージョンアップして 2.4.0 がリリースされたようなので、アップデートしてみました。
「update」コマンドを実行して、電源ケーブルを繋いで、あとは待つだけでした。「数時間掛かる」みたいなメッセージが出ましたが、30分も掛からず完了しました。
アップデート完了すると、Web 経由で「シール」をダウンロードできました。以下がダウンロードしたシール。
FuelPHP 入門ハンズオン vol.2 を開催しました
昨日、FuelPHP 入門ハンズオン vol.2 を、名古屋で開催しました。
このハンズオンは PHP に関する基本的な知識がある方を対象に、FuelPHP のインストールから使い始めることができるようになるまでを目標とするものです。 今回、2回目ですが、東は浜松から、西は奈良からと遠方より参加される方もいらっしゃいました。
前回より 1時間ほど時間の余裕がありましたが、内容的には前回と同一の範囲をカバーするものになりました。詳細に興味のある方は、以下のスライドをご覧ください。
Git & GitHub を使ったことがない人が多く、また、今回は、Windows マシン(GitHub for Windows の動作がおかしいなど)でのトラブルと XAMPP for Mac でのトラブル(MySQL データベースに接続できない)が発生し、そこで時間を食いました。トラブルの発生をおさえることと、トラブル発生時の対応をどうするかが、今後の課題だと思います。
それと、FuelPHP 以前に Git のハンズオンが必要なような気がします。
FuelPHP 1.6.1 で SQLite を使い Scafold する
SQLite でも Scafold したコードが動きましたので、手順を書いておきます。
あまりきちんと検証していないので、SQLite の設定など改善すべき点がありましたら、お知らせ頂けるとありがたいです。
config.php で orm を always_load するようにします。
データベース設定を SQLite にします。
--- a/fuel/app/config/development/db.php +++ b/fuel/app/config/development/db.php @@ -5,10 +5,15 @@ return array( 'default' => array( - 'connection' => array( - 'dsn' => 'mysql:host=localhost;dbname=fuel_dev', - 'username' => 'root', - 'password' => 'root', + 'connection' => array( + 'dsn' => 'sqlite:' . APPPATH . 'tmp/sample.sqlite3', + 'persistent' => false, + 'compress' => false, ), + 'identifier' => '"', + 'table_prefix' => '', + 'enable_cache' => true, + 'profiling' => true, + 'charset' => '', ), );
oil コマンドで scaffold します。
$ php oil generate scaffold bbs post_date:date message:varchar[100] --singular
migration ファイルがそのままでは動かないので修正します。
--- a/fuel/app/migrations/001_create_bbs.php +++ b/fuel/app/migrations/001_create_bbs.php @@ -7,13 +7,12 @@ class Create_bbs public function up() { \DBUtil::create_table('bbs', array( - 'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true, 'unsigned' => true), - 'post_date' => array('type' => 'date'), - 'message' => array('constraint' => 100, 'type' => 'varchar'), - 'created_at' => array('constraint' => 11, 'type' => 'int', 'null' => true), - 'updated_at' => array('constraint' => 11, 'type' => 'int', 'null' => true), - - ), array('id')); + 'id' => array('type' => 'integer primary key', 'autoincrement' => true), + 'post_date' => array('type' => 'text'), + 'message' => array('type' => 'text'), + 'created_at' => array('type' => 'integer', 'null' => true), + 'updated_at' => array('type' => 'integer', 'null' => true), + )); } public function down()
oil コマンドで migrate します。
$ php oil refine migrate
views/bbs/index.php がバグっているので修正します。これは、--singular オプションを付けたときに発生するバグです。
--- a/fuel/app/views/bbs/index.php +++ b/fuel/app/views/bbs/index.php @@ -10,14 +10,14 @@ </tr> </thead> <tbody> -<?php foreach ($bbs as $bbs): ?> <tr> +<?php foreach ($bbs as $bb): ?> <tr> - <td><?php echo $bbs->post_date; ?></td> - <td><?php echo $bbs->message; ?></td> + <td><?php echo $bb->post_date; ?></td> + <td><?php echo $bb->message; ?></td> <td> - <?php echo Html::anchor('bbs/view/'.$bbs->id, '<i class="icon-eye-open" title="View"></i>'); ?> | - <?php echo Html::anchor('bbs/edit/'.$bbs->id, '<i class="icon-wrench" title="Edit"></i>'); ?> | - <?php echo Html::anchor('bbs/delete/'.$bbs->id, '<i class="icon-trash" title="Delete"></i>', array('onclick' => "return confirm('Are you sure?')")); ?> + <?php echo Html::anchor('bbs/view/'.$bb->id, '<i class="icon-eye-open" title="View"></i>'); ?> | + <?php echo Html::anchor('bbs/edit/'.$bb->id, '<i class="icon-wrench" title="Edit"></i>'); ?> | + <?php echo Html::anchor('bbs/delete/'.$bb->id, '<i class="icon-trash" title="Delete"></i>', array('onclick' => "return confirm('Are you sure?')")); ?> </td> </tr>
Linux で Internet Explorer 6,7,8,9,10 での表示を確認する
http://www.modern.ie/ja/virtualization-tools から Linux 用の仮想マシン(VirtualBox)をダウンロードします。
IE9.Win7.For.LinuxVirtualBox の場合は、以下のようにします。
$ wget -c i https://az412801.vo.msecnd.net/vhd/IEKitV1_Final/VirtualBox/Linux/IE9_Win7/IE9.Win7.For.LinuxVirtualBox_2.txt
ダウンロードが完了したら、解凍します。
$ chmod +x IE9.Win7.For.LinuxVirtualBox.part1.sfx $ ./IE9.Win7.For.LinuxVirtualBox.part1.sfx
「IE9 - Win7.ova」が作成されました。これを VirtualBox にインポートします。
オーバーロードされたプロパティと emtpy() 〜 nagoya.php vol.2 での話
http://blog.ohgaki.net/php-5-4-accessor-php にある trait を使ったアクセサのサンプルコード(微妙にいじってますが、ロジックは全く同じです)。
<?php // Example code how to eliminate getter and setter methods // with traits introduced from PHP 5.4 trait Accessors { public function __get($name) { if ($this->r_property[$name]) { return $this->$name; } else { trigger_error("Access to read protected property"); } } public function __set($name, $value) { if ($this->w_property[$name]) { $this->$name = $value; } else { trigger_error("Access to write protected property"); } } } class OrderLine { use Accessors; private $r_property = array('price' => 1, 'amount' => 1); private $w_property = array('price' => 0, 'amount' => 1); protected $price = 100; private $amount; private $tax = 1.15; // property without getter/setter public function getTotal() { return $this->price * $this->amount * $this->tax; } } $line = new OrderLine; //$line->price = 20; // Notice error $line->amount = 3; echo "Total cost: ".$line->getTotal(), PHP_EOL;
で、上記のようなコードで、オーバーロードされたプロパティを emtpy() したら true が返ってハマったというのが、nagoya.php での話でした。
var_dump(empty($line->amount)); // true
これは、PHP の仕様です。
PHP マニュアルの「注意」
ここで、以下のような注意が PHP にマニュアルにありました。
注意:
オーバーロードされたプロパティを、 isset() 以外の言語構造の中で使うことはできません。 つまり、オーバーロードされたプロパティに対して empty() がコールされたとしても、オーバーロードされたメソッドはコールされないということです。
この制約を回避するには、オーバーロードされたプロパティを そのスコープのローカル変数にコピーしてから empty() に渡さなければなりません。
http://www.php.net/manual/ja/language.oop5.overloading.php
これ、何なんでしょう?
「オーバーロードされたプロパティを、 isset() 以外の言語構造の中で使うことはできません」→ isset() なら使えるの?使えないですよね。
var_dump(isset($line->amount)); // false
empty() と isset() どちらも同じようにオーバーロードされたプロパティでは機能しません。
ということで、この「注意」はちょっとよくわかりません。ただの間違い?
あと、「この制約を回避するには、オーバーロードされたプロパティを そのスコープのローカル変数にコピーしてから empty() に渡さなければなりません」→ つまり、empty() 使いたかったら、こうしろと。
$amount = $line->amount; var_dump(empty($amount)); // false
しかし、そんなことを強制するのは、正直、無理っぽいですよね。
どうすればいいのか?
__isset() を定義すればいいと思うよ。
<?php // Example code how to eliminate getter and setter methods // with traits introduced from PHP 5.4 trait Accessors { public function __get($name) { echo '__get():'; if ($this->r_property[$name]) { return $this->$name; } else { trigger_error("Access to read protected property"); } } public function __set($name, $value) { echo '__set():'; if ($this->w_property[$name]) { $this->$name = $value; } else { trigger_error("Access to write protected property"); } } public function __isset($name) // これです { echo '__isset():'; if ($this->r_property[$name] === 1) { return true; } else { return false; } } } class OrderLine { use Accessors; private $r_property = array('price' => 1, 'amount' => 1); private $w_property = array('price' => 0, 'amount' => 1); protected $price = 100; private $amount; private $tax = 1.15; // property without getter/setter public function getTotal() { return $this->price * $this->amount * $this->tax; } } $line = new OrderLine; //$line->price = 20; // Notice error $line->amount = 3; echo "Total cost: ".$line->getTotal(), PHP_EOL; var_dump(isset($line->amount)); var_dump(empty($line->amount));
そうすると、結果は、以下のようになります。
__set():Total cost: 345 __isset():bool(true) __isset():__get():bool(false)
ちなみに、この話、trait は関係ありません。