2

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?

HenningCash
  • 2,030
  • 18
  • 17
  • I'm going to put this as a comment since the Lith docs are less than clear and I haven't got an install of Lith to try it on however any field not in the `$validates` property should not be set within the model from the POST so merely omitting fields like `created_date` from that property should stop it from being set. I would personally test it. – Sammaye Oct 14 '12 at 13:01
  • Sadly not, the validator simply ignores other values that are not set for validation. So they finally get into the database.. Even the validator "blank" does not work properly – HenningCash Oct 14 '12 at 13:09

1 Answers1

4

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.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
rmarscher
  • 5,596
  • 2
  • 28
  • 30
  • Thanks! Exactly what I looked for. Thought it's a feature Lithium has not included, but I start loving this framework! – HenningCash Oct 14 '12 at 14:17
  • Yeah, the documentation still has quite a bit of holes, but the code is very solid. The documentation should get better over the coming months as the framework is getting very close to a 1.0 release. A recommendation from one of the core team members was to read through the tests because every aspect of the framework should have an accompanying unit test. – rmarscher Oct 14 '12 at 21:19