Advent Calendar何か書こうかなーと思っていた時に、ふと思い立ちプラグインを作成しました。
セキュリティ対策としてViewで扱う文字列にはHTMLエスケープが必要です。
CakePHPにはh()
というhtmlspecialchars()
をサクッと使えるものがあります。
が、
大規模なシステムになってくるとどうしても抜けが派生しがち。
その抜けをなくすためのplugin for CakePHP3を作成してみました。
要はh()
なんて書かずにすべてエスケープされてやればいいんだ!
リポジトリ
name : Altair
github : https://github.com/tutida/altair
composer : https://packagist.org/packages/tutida/altair
参考にしたPlugin
k1low/escape : https://github.com/k1LoW/escape
やってること
ControllerからViewクラスに渡される変数は全て「$viewVars」に格納されるので、それを無差別にHTMLエスケープしてます。
使い方
//AppController
class AppController extends Controller
{
public function initialize()
{
$this->loadComponent('Altair.Altair');
}
これだけで、viewのほうで毎回、<?= h($variable); ?>
とか書かずに済みます。
//エスケープ済み
<td><?= $user->username ?></td>
<td><?= $user->password ?></td>
<td><?= $user->created ?></td>
<td><?= $user->modified ?></td>
CakePHP2との違い
find()の返り値がオブジェクト
CakePHP2の場合、paginate()やfind()の結果は配列でしたが、
CakePHP3よりそのあたりがオブジェクトとなったので、HTMLエスケープをするのか多少面倒。
formへ入力される値はデコードする必要あり
CakePHP2の場合、edit画面などでformへ入力される値は$viewVars
ではなく$this->requst->data
を参照していました。
CakePHP3の場合は、$viewVars
に格納されているformに対応するEntityオブジェクとを参照するため、
すべての変数を無差別にHTMLエスケープしている実装だと、formに入る値もエスケープされてしまいます
なので、FormHelperを継承したDecodeFromHelperをPluginに含めています。
inputに入力される値は再びデコードする仕様です。
※なので、FormHelperを別でオーバーライドする場合は意図通りの動きをしません...
何かいい案あったら是非ご意見を。
是非機会があれば使ってみてください。
穴だらけだと思うので、皆さんのフィードバックで育てていきたいと思います。