Question

I'm writing my first community page with Lithium and mongoDB. I really like the schema-less way of mongo, but there is one problem making it impossible working without a schema:

For instance we have a simple form like this:

<?=$this->form->create();?>
<?=$this->form->field('name',array('label' => 'Topic title'));?>
<?=$this->form->field('text',array('label' => 'Content'));?>
<?=$this->form->submit('create');?>

which will be even simpler saved by this:

if($this->request->is('post')) {
    $board_post = BoardPosts::create($this->request->data);
    $board_post->save();
}

Now it's possible for everyone to add some form inputs by DOM manipulation with Firebug, Developer Tools etc. Of course that it might be some sensless fields in the database, but maybe someone adds a field, that is really used. The only way to prevent this, is creating a schema in model. But for me this makes the whole idea of a schema-less database useless, doesn't it? And how to make schemas for different situations/actions, when some fields must not occur?

Was it helpful?

Solution

The Model::save() method accepts a 'whitelist' param in its options. See http://li3.me/docs/lithium/data/Model::save()

$whitelist = array(
    'title',
    'text'
);
$post = BoardPosts::create();
$post->save($this->request->data, compact('whitelist')); 

You can also define protected $_schema in your Model and set protected $_meta = array('locked' => true); which will automatically set the whitelist to the fields defined in your schema. However, it is a good idea to define the whitelist in your controller to avoid attacks like you describe.

This problem is called a mass-assignment vulnerability and exists in many frameworks if developers are not careful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top