The best way to protect model->load() from saving wrong inputs

In yii2 app I have User model. For example, I have fields name and is_admin (0 or 1). When user signs up, he enters name only.

He has user/update page to edit his name. But, if you are admin, you can also edit everyones page and set is_admin field also (for admins it is visible on page).

Rules are like:


public function rules()

{

    return [

        ['name', 'string'],

        ['is_admin', 'integer'],

    ];

}

Q: How to protect action from ability users to set them admins from user/update page by putting another <input name="User[…]">?

That means everyone can replace input attribute name="User[name]" to name="User[is_admin]" and set value to 1. Then $model->load(Yii::$app->request->post()) automatics sets is_admin var.

Yes, I can by hand empty is_admin in $_POST, but in real project I have 20+ fields in db table and a lot of actions, it is hard everytime to check what inputs I have in every view and compare.

Controller:


$model = User::findIdentity($id);


if ($model->load(Yii::$app->request->post())) {

    if ($model->save())

        ...

}

Just add another validation rule you model




public function rules()

{

	return [

    	['name', 'string'],

    	['is_admin', 'integer'],

    	[['is_admin'], 'validateAdmin'],

	];

}


public function validateAdmin($attribute, $params) {

	// You check if the current user is an admin, therefore can change admin status to other user

	// I assume that you save admin flag in user identity

	if (Yii::$app->user->identity->is_admin==0) {

        	// the current user is NOT admin

   	     // if the validation run probably the user tried to inject the is_admin field value

	        // therefore we trow an error to the user

 	       // when you add an error the validation fail, no need to return false, therefore the data is not saved

 	       $this->addError($attribute, 'You are not allow to change admin status!');

	}

}