$filedList設定でフィールド追加攻撃対策
複数の関連モデルの同時登録の方法を調べていて、save()に、$fieldListという設定があることを知りました。
http://book.cakephp.org/ja/view/75/Saving-Your-Data
例えば、usersのgourp_idという項目はユーザ変更不可なのだけど、usersのedit画面にデータをPOSTするときにgroup_idを追加して書き換える・・・というようなハッキングへの対策なのですが、
この機能、あると知らなかったのでbeforeSave()に自前で入れてました (^^;)
公式機能使用に変更。
(1/29 17:22) saveAllに関する記載について、訂正UPしました
フィールド指定はホワイトリスト方式。
単独のモデルに対してsave()する場合の例。
app/controllers/users_controller.php
- if ($this->User->save($this->data)) { + if ($this->User->save($this->data, array('fieldList' => $this->User->fields['edit']))) {
上が変更前、基本のsave()。
第二引数にフィールド名の配列指定を追加すると、指定のないfieldは更新されません*1。
フィールドリストは、モデルに作って管理してます。
app/model/users.php
var $fields = array( 'add' => array('group_id', 'name', 'username', 'password'), 'edit' => array('name'), );
通常の編集アクションではパスワード変更できませんが、パスワード変更アクションでは、以下の様に書くと変更可能になります。
$this->User->save($this->data, array('fieldList' => array('password'));
また、発端の「複数の関連モデルの同時登録」の場合、saveAll()を使いますが、
$fieldListの指定にテーブル名も入れる点のみ違いと、hasMany側を複数同時更新する場合はで、基本、saveとほぼ同様にOKでした。
上記、関連モデルの状態によってはNGでした・・・確認中
(上、テーブル名は入れると返ってNGです。検証)
controller
/* 保存 */ $this->data['Character']['id'] = $id; if ($this->Character->saveAll($this->data, array( 'validate' => false, 'atomic' => true, 'fieldList' => array_merge( $this->Character->fields['edit'], $this->Character->CharactersHasProfile->fields['add'])
Model
Character
var $fields = array( 'edit' => array('Character.name', 'Character.sort_order', 'Character.status', 'Character.public_flag', 'Character.detail'),
CharactersHasProfile
var $fields = array( 'add' => array('CharactersHasProfile.profile_id', 'CharactersHasProfile.profile_select_id', 'CharactersHasProfile.profile_table_id', 'CharactersHasProfile.value', 'CharactersHasProfile.public_flag', 'CharactersHasProfile.link_value'), // Character連携対応
CakePHP的には、関連モデルの予定がなくても、table名.field で指定する方が厳密で、良い様ですが・・・
*1:エラーもでてない模様