Search code examples
node.jsmongoosemass-assignment

How to protect fields from mass assignment in Mongoose?


A Mongoose model, Thing, has two fields, only one of which (safe) should be settable through mass assignment:

var db = require('mongoose');

var schema = new db.Schema({
  safe:   { type: String }, // settable through mass assignment
  unsafe: { type: String }  // not settable through mass assignment
});

db.model('Thing', schema);

A controller sets up Thing by passing parameters:

exports.create = function(req, res) {
  var thing = new Thing(req.body);

  // more...
};

An attacker could try to set thing.unsafe by making a JSON POST request in which unsafe is set. This should be prevented.

It would be great if something like the Rails attr_accessible functionality were available for Mongoose. I did find mongoose-mass-assign, but this is nothing like what I'm looking for. For one thing, mongoose-mass-assign apparently requires the use of a new API (two massAssign functions). I want mass assignment protection for any native Mongoose model function to which params hashes are passed, for example, the Thing constructor and the Thing.create function.

How can I get mass assignment protection for Mongoose models? If not available, how do Mongoose users currently protect against this vulnerability?


Solution

  • Facepalm:

    var thing = new Thing(req.body);
    

    Slightly saner:

    var okFields = {};
    okFields.safe = req.body.safe
    var thing = new Thing(okFields);
    //Also helpful for longer whitelists from underscore: _.pick(req.body, "safe");
    //Also feel free to add some, y'know, data validation either here or in mongoose
    

    Just don't do that. Rails has taught you a terrible antipattern. But to answer your question, AFAIK mongoose nor mongodb has no mechanism to enforce anything analogous to rails's attr_accessible or any concept of tainted variables.