Introduction

Attackers can sometimes use this methodology to create new parameters that the developer never intended which in turn creates or overwrites new variable or objects in program code that was not intended.

This is called a Mass Assignment vulnerability.

Alternative Names

Depending on the language/framework in question, this vulnerability can have several alternative names:

  • Mass Assignment: Ruby on Rails, NodeJS.
  • Autobinding: Spring MVC, ASP NET MVC.
  • Object injection: PHP.

Example

Suppose there is a form for editing a user’s account information:

Here is the object that the form is binding to:

  1. private String userid;
  2. private String password;
  3. private String email;
  4. private boolean isAdmin;
  5. //Getters & Setters
  6. }

Here is the controller handling the request:

  1. @RequestMapping(value = "/addUser", method = RequestMethod.POST)
  2. public String submit(User user) {
  3. userService.add(user);
  4. return "successPage";
  5. }

Here is the typical request:

  1. POST /addUser
  2. userid=bobbytables&password=hashedpass&email=bobby@tables.com

And here is the exploit in which we set the value of the attribute isAdmin of the instance of the class User:

Exploitability

  • Attacker can guess common sensitive fields.
  • Attacker has access to source code and can review the models for sensitive fields.
  • AND the object with sensitive fields has an empty constructor.

GitHub case study

In 2012, GitHub was hacked using mass assignment. A user was able to upload his public key to any organization and thus make any subsequent changes in their repositories. GitHub’s Blog Post.

Solutions

  • Whitelist the bindable, non-sensitive fields.
  • Blacklist the non-bindable, sensitive fields.
  • Use Data Transfer Objects (DTOs).

General Solutions

An architectural approach is to create Data Transfer Objects and avoid binding input directly to domain objects. Only the fields that are meant to be editable by the user are included in the DTO.

  1. public class UserRegistrationFormDTO {
  2. private String userid;
  3. private String password;
  4. private String email;
  5. //NOTE: isAdmin field is not present
  6. //Getters & Setters
  7. }

Language & Framework specific solutions

  1. @Controller
  2. public class UserController
  3. {
  4. @InitBinder
  5. public void initBinder(WebDataBinder binder, WebRequest request)
  6. {
  7. }
  8. ...
  9. }

Take a look for the documentation.

Blacklisting

  1. @Controller
  2. public class UserController
  3. {
  4. @InitBinder
  5. public void initBinder(WebDataBinder binder, WebRequest request)
  6. {
  7. binder.setDisallowedFields(["isAdmin"]);
  8. }
  9. ...
  10. }

Take a look for the documentation.

NodeJS + Mongoose

Take a look for the documentation.

Blacklisting

  1. var massAssign = require('mongoose-mass-assign');
  2. var UserSchema = new mongoose.Schema({
  3. userid: String,
  4. password: String,
  5. email : String,
  6. isAdmin : { type: Boolean, protect: true, default: false }
  7. });
  8. UserSchema.plugin(massAssign);
  9. var User = mongoose.model('User', UserSchema);
  10. /** Static method, useful for creation **/
  11. var user = User.massAssign(req.body);
  12. /** Instance method, useful for updating**/
  13. var user = new User;
  14. user.massAssign(req.body);
  15. /** Static massUpdate method **/
  16. var input = { userid: 'bhelx', isAdmin: 'true' };
  17. User.update({ '_id': someId }, { $set: User.massUpdate(input) }, console.log);

Take a look for the documentation.

Ruby On Rails

Take a look for the documentation.

Django

Take a look for the documentation.

ASP NET

PHP Laravel + Eloquent

  1. <?php
  2. namespace App;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. private $userid;
  7. private $password;
  8. private $email;
  9. private $isAdmin;
  10. protected $fillable = array('userid','password','email');
  11. }

Take a look here for the documentation.

Blacklisting

  1. <?php
  2. namespace App;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. private $userid;
  7. private $password;
  8. private $email;
  9. private $isAdmin;
  10. protected $guarded = array('isAdmin');

Take a look here for the documentation.

Take a look for the documentation.

Play

Take a look for the documentation.

Jackson (JSON Object Mapper)

Take a look and here for the documentation.

GSON (JSON Object Mapper)

Take a look here and for the document.

JSON-Lib (JSON Object Mapper)

Take a look for the documentation.

Flexjson (JSON Object Mapper)

Take a look for the documentation.

References and future reading