CakePHP2のセキュリティコンポーネントでCSRF対策のみ行う
CakePHP1のセキュリティコンポーネントは、CSRF対策と、フォーム改竄対策がセットであるため、例えばjavascriptで動的にフォームなどを追加するとチェックに引っかかります。
CakePHP2からは、CSRF対策とフォーム改竄対策がそれぞれオプションでOFFにできます(デフォルトではどちらも有効)
CSRF対策のみ行いたい場合は、コントローラのコンポーネント指定でvalidatePostをfalseにします。
public $components = array( 'Security' => array('validatePost' => false), );
動的にON/OFFを切り替えたい場合は、コントローラで下記のようにできます。
$this->Security->validatePost = false; //改竄対応 $this->Security->csrfCheck = false; //CSRF対応
下記に詳しく書いてあります。
http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#form-tampering-prevention
CakePHP2 独自SQL文でPrepared Statementを使う
CakePHP1系では、
Model->query('select * from posts where id=?', array('hoge'));
みたいにして擬似バインドできましたが、CakePHP2からは下記の方法でやるとPrepared StatementでSQLを発行してくれます。
// in controller $result = $this->Post->getDatasource()->fetchAll( 'select * from posts as Post where Post.id = ? or Post.id = ?', array(1, "abc") ); $result = $this->Post->getDatasource()->fetchAll( 'select * from posts as Post where Post.id = :id or Post.id = :id2', array('id'=>1, 'id2' => 2) );
詳細は下記に。
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#prepared-statements
[追記] 2013/1/29
CakePHP2.1を確認したところ、Model::query()のものは、すべてfetchAll()に渡されるため、擬似バインドではなく、Prepared Statementになってました。
よかった。
Model::query()を使ったほうが記述が楽なので、そっちを使っていれば良いですね。
[追記] 2013/1/28
デフォルトだとキャッシュが効いてしまうので、第3引数にarray('cache' => false)を渡せばキャッシュ無効にできます
http://api.cakephp.org/class/dbo-source#method-DboSourcefetchAll
// in controller $result = $this->Post->getDatasource()->fetchAll( 'select * from posts as Post where Post.id = ? or Post.id = ?', array(1, "abc"), array('cache' => false) );
ここで言っているキャッシュとは、1回のアクセスの中でのみ利用されるため、1アクセスで同じクエリが複数回実行されるものに限り有効になります。
[追記]
Prepared Statementsでバインドした値が、sql_debug画面に出なかったのでパッチ書いて送りました。
CakePHP2.1ブランチで取り込まれました
https://github.com/cakephp/cakephp/commit/e8a9d93eb52cdff15acee789a89e3c569da9b259