CakePHPの防御力を試す1〜SQLインジェクション〜

CakePHP 1.3.2】

CakePHPのデフォルトの状態で、どこまでセキュリティ対策が
施されているのかを実験します。

【実験方法】
デバッグを"2"に設定し、予想される攻撃によってどのような
SQLが生成されるのかを確認します。

【/app/config/core.php
Configure::write('debug', 2);

1. SQLインジェクション

【実験環境】
下記の3つのメソッドについて、CakePHPの対応を見てみます。
  • read()
  • find()
  • findById()


【コントローラ】
function view($id){
//【1】
$this->data = $this->User->read(null, $id);

//【2】
$this->data = $this->User->find('first',
array('conditions'=>array('User.id'=>$id)
));

//【3】
$this->data = $this->User->findById($id);
}
//※実際には、同時ではなく個別に実行します。

viewアクションへ渡すユーザIDのパラメータの後に攻撃用の
SQLを続けて記述し、ブラウザでアクセスしてみます。
(『'』とは、『'』の文字実体参照です)
  1. example.com/users/view/12; select * from users;
  2. example.com/users/view/12;'select * from users;
  3. example.com/users/view/12;'select * from users;

【生成されたSQL
  1. ... WHERE `User`.`id` = '12;select * from users;'
  2. ... WHERE `User`.`id` = '12;\'select * from users;'
  3. ... WHERE `User`.`id` = '12;\'select * from users;'
すべて、攻撃を防ぐことができました。
read、find、findById、それぞれ上記の攻撃例で生成された
SQLは同じでした。

2. 比較演算子インジェクション

【実験環境】
下記の2つのメソッドについて、CakePHPの対応を見てみます。
  • $form->input()
  • $form->text()


テキストボックスに攻撃用の比較演算子とユーザ情報(この場合は
メールアドレス)を記述し、フォーム送信してみます。

  1. != hoge@fuga.com
  2. '!= hoge@fuga.com
  3. ;'!= hoge@fuga.com

【生成されたSQL
  1. ... WHERE `User`.`mail` = '!= hoge@fuga.com'
  2. ... WHERE `User`.`mail` = '\'!= hoge@fuga.com'
  3. ... WHERE `User`.`mail` = ''!= hoge@fuga.com'
すべて、攻撃を防ぐことができました。
$form->input()、$form->text()、それぞれ上記の攻撃例で生成された
SQLは同じでした。


感想

CakePHP 1.1の頃は、セキュリティのために初期状態にちょっと
手を加える必要がありましたが、1.2以降はfindの構造が変わったので
手間が省けて便利になったようです。


次回は、クロスサイトスクリプティング(XSS)について
実験してみたいと思います。