カテゴリー
コンピューター

CakePHP2 でパラメータ改ざん対策。フォームの入力値以外を変更しない方法

post のデータに予期しない値が混じっているとセキュリティ上よくないです。悪意ある攻撃者がフォームに存在しないフィールドを予想して、意図しない DB テーブルのカラムを書き換える、ということがおきるかもしれません。

パラメータ改ざん対策が必要です。

そこで、入力フォームで指定したフィールドのみを確実に受け付けるようにする方法を考えました。

考えた方法

  • 入力フォームのフィールドをコントローラーやモデルなどサーバサイドで取り出して新しい変数に入れる。

例です。

app/Controller/UsersController.php

<?php
App::uses('AppController', 'Controller');
/**
 * Users Controller
 *
 * @property User $User
 */
class UsersController extends AppController {

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		$this->User->id = $id;
		if (!$this->User->exists()) {
			throw new NotFoundException(__('Invalid user'));
		}

		if ($this->request->is('post') || $this->request->is('put')) {

			// 入力フォームの値のみを保存するため、それら以外の post データを排除する。
			$save_data['User']['id'] = $this->request->data['User']['id'];
			$save_data['User']['username'] = $this->request->data['User']['username'];
			$save_data['User']['password'] = $this->request->data['User']['password'];
			$save_data['User']['group_id'] = $this->request->data['User']['group_id'];
			$save_data['Profile']['id'] = $this->request->data['Profile']['id'];
			$save_data['Profile']['catch_phrase'] = $this->request->data['Profile']['catch_phrase'];
			$save_data['Profile']['self_introduction'] = $this->request->data['Profile']['self_introduction'];
			$save_data['Profile']['ExProfile']['id'] = $this->request->data['Profile']['ExProfile']['id'];
			$save_data['Profile']['ExProfile']['job'] = $this->request->data['Profile']['ExProfile']['job'];

			if ($this->User->saveAll($save_data, array('deep' => true))) {
				$this->Session->setFlash(__('The user has been saved'));
				$this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
			}
			/*
		*/
		} else {
			$this->User->recursive = 2;
			$this->request->data = $this->User->read(null, $id);
		}
		$groups = $this->User->Group->find('list');
		$this->set(compact('groups'));
	}
}

行っていることは単純で、フォームのフィールドと同じフィールド名で新しく配列の変数を作って、 post のフィールドデータを入れているだけです。

コントローラーで行っていますが、本当はモデルで行うべき処理だと思います。

app/View/Users/edit.ctp

<div class="users form">
<?php echo $this->Form->create('User'); ?>
	<fieldset>
		<legend><?php echo __('Edit User'); ?></legend>
	<?php
		echo $this->Form->input('User.id');
		echo $this->Form->input('User.username');
		echo $this->Form->input('User.password');
		echo $this->Form->input('User.group_id');
		echo $this->Form->input('Profile.id');
		echo $this->Form->input('Profile.catch_phrase');
		echo $this->Form->input('Profile.self_introduction');
		echo $this->Form->input('Profile.ExProfile.id');
		echo $this->Form->input('Profile.ExProfile.job');
		echo $this->Form->input('Profile.ExProfile.address');
	?>
	</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

特筆する点はありません。

おわりに

Security コンポーネントを使っていれば、この仕組みは自動で組み込まれています。「Form tampering protection」です。

また、こちらのページもすばらしいです。CakePHP1.3 の情報ですけれども、Security コンポーネント、パラメータ改ざん対策についての理解が深まりました。ありがとうございます。

コメントを残す