雑文発散

«前の日記(2010-02-20) 最新 次の日記(2010-02-27)» 編集
過去の日記

2010-02-25 [長年日記]

[tDiary] 第三tDiary.Netの tDiary をバージョンアップしました

tDiary 2.2.2 およびそれ以前のバージョンにクロスサイトスクリプティング(XSS)脆弱性が発見されたため、tDiary 2.2.3 がリリースされました。

これに伴ない、第三tDiary.Netで稼働している tDiary も 2.2.3 へバージョンアップしました。特に動作に影響はないと思いますが、何かあればこの日記にツッコミをお願いします。

なお、脆弱性についての詳細は、tDiary開発プロジェクトによる下記の記事を参照してください。

tDiaryの脆弱性に関する報告(2010-02-25)

[CakePHP] Component の中から Cookie Component を呼んで悩んだこと

ひさびさに CakePHP を触っているんだけど、自作 Component の中から CookieComponent を呼んだときに、ちょっとハマってたので記してみる。

Cookie Component の基本的な使い方はこんな感じ。

<?php
class SamplesController extends AppController
{
    var $name = 'Samples';
    var $uses = array();
    var $components = array('Cookie');
 
    function beforeFilter()
    {
        $this->Cookie->name = 'samplecookie';
        $this->Cookie->time = 3600;
    }
 
    function test()
    {
        $this->Cookie->write('hoge', 'fuga', FALSE);
    }
}
?>

これで /samples/test へアクセスしたときに発行される Cookie はこのようになる。

Set-Cookie: samplecookie[hoge]=fuga; expires=Thu, 25-Feb-2010 15:25:58 GMT; path=/

$this->Cookie->name で設定した samplecookie が Cookie 名に入っており、$this->Cookie->time で設定した値を元に expires の日時が入っているのが分かる。

次に自作の Component の中から Cookie コンポーネントを呼び出して、使ってみる。Controller では、自作 Component だけを呼び出すようにしている。

<?php
class SamplesController extends AppController
{
    var $name = 'Samples';
    var $uses = array();
    var $components = array('Original');
 
    function test()
    {
        $this->Original->func1();
    }
}
?>

Component の中からは、別の Component を呼び出す場合、Controller と同じように $components へ指定してやれば良いことになっているので、自作の Component からは、このように Cookie Component を呼び出した。

また、Component には beforeFilter() が無いので、initialize() に Cookie Component の設定を書いてみた。

<?php
class OriginalComponent extends Object
{
    var $components = array('Cookie');
 
    function initialize(&$controller)
    {
        $this->Cookie->name = 'samplecookie';
        $this->Cookie->time = 3600;
    }
 
    function func1()
    {
        $this->Cookie->write('hoge','fuga',FALSE);
    }
}
?>

このコードで発行された Cookie は、最初のコードと同じように Cookie 名と expires がセットされることを期待していたのだが、実際に吐き出された Cookie には expires が付いていなかった。

Set-Cookie: samplecookie[hoge]=fuga; path=/

なんで?なんで?なんで?としばらく悩んでいたのだが、Cookie Component の中身を見て、ようやく分かった。

$this->Cookie->time で設定した値は、Cookie Component 内の startup() でのみ利用されており、また、startup() は Controller から呼ばれた場合に実行される処理らしい*1ので、上記のように initialize() などで time をセットしても、この値は利用されないのであった。

じゃあ、どうすれば良いのか?であるが、$this->Cookie->write() の第4引数に expires 設定を書いてやれば、やりたいことはできる。

<?php
class OriginalComponent extends Object
{
    var $components = array('Cookie');
 
    function initialize(&$controller)
    {
        $this->Cookie->name = 'samplecookie';
    }
 
    function func1()
    {
        $this->Cookie->write('hoge','fuga',FALSE, 3600);
    }
}
?>

このコードを実行すると expires 付きの Cookie を発行してくれる。

Set-Cookie: samplecookie[hoge]=fuga; expires=Thu, 25-Feb-2010 15:54:42 GMT; path=/

$this->Cookie->name も利用されないなら、割と早く気がついたかも知れないんだけど、$this->Cookie->time だけが利用されない状態だったので、意外とハマって、悩んでしまったよ。

*1 コードは未確認。実行状況で確認した。