I’ve got a CGridView with links for each entry and each link is like this:
The id here is the unique identifier of the Model instance currently being displayed. So there’s a security issue, a user could enter in the browser the URL with any id.
One of the solution I can think of is to maintain an array in the session like this array(0=>231, 1=>245, 2=>432) and the link would be
and the controller’s action would figure out from the array that id 231 must be displayed.
Is there a better solution ?
This is not a security problem of CGridView, it’s an issue of handling actionView, actionUpdate, … in the controller.
But for example you can use scopes there like ‘published’, ‘ownOnly’ …
You have to add the security to your loadModel method in your CRUD-Controller:
class PostController extends Controller
public function actionView($id)
public function actionUpdate($id)
public function loadModel($id)
$model=Post::model()->published()->ownOnly()->findByPk((int)$id); //use scopes
throw new CHttpException(404,'The requested page does not exist.');
Your model code
class Post extends CActiveRecord
public function scopes()
So in essence what you are suggesting is that I can leave the ids in the URL and just handle the security in the model, making sure that the record does belong to the right person. And I can use scopes to handle this more gracefully.
You always should control the loaded data in the controllers action,
because the url is accessible from everywere (if not filtered in controller accessControl/rules): CGridView, CListview, custom view, enter in the browser …
And using named scopes is a comfortable way to make defined conditions reusable.
You can use it on creating the dataprovider too:
* Lists all models.
public function actionIndex()