This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
Difference between revisions of "Mass Assignment Cheat Sheet"
m (NodeJS code sample update) |
m (→Data Transfer Objects (DTOs)) |
||
Line 89: | Line 89: | ||
private String email; | private String email; | ||
− | // | + | //NOTE: isAdmin field is not present |
//Getters & Setters | //Getters & Setters |
Revision as of 23:31, 21 December 2016
Last revision (mm/dd/yy): 12/21/2016
IntroductionDefinitionSoftware frameworks sometime allow developers to automatically bind HTTP request parameters into program code variables or objects to make using that framework easier on developers. This can sometimes cause harm. 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 NamesDepending on the language/framework in question, this vulnerability can have several alternative names
ExampleSuppose there is a form for editing a user's account information: <form> <input name=userid type=text> <input name=password type=text> <input name=email text=text> <input type=submit> </form> Here is the object that the form is binding to: public class User { private String userid; private String password; private String email; private boolean isAdmin; //Getters & Setters } Here is the controller handling the request: @RequestMapping(value = "/addUser", method = RequestMethod.POST) public String submit(User user) { userService.add(user); return "successPage"; } Here is the typical request: POST /addUser userid=bobbytables&password=hashedpass&[email protected] And here is the exploit: POST /addUser userid=bobbytables&password=hashedpass&[email protected]&isAdmin=true ExploitabilityThis functionality becomes exploitable when:
Case StudiesGitHubIn 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
General SolutionsData Transfer Objects (DTOs)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. public class UserRegistrationFormDTO { private String userid; private String password; private String email; //NOTE: isAdmin field is not present //Getters & Setters } Language & Framework Specific SolutionsSpring MVCWhitelisting@Controller public class UserController { @InitBinder public void initBinder(WebDataBinder binder, WebRequest request) { binder.setAllowedFields(["userid","password","email"]); } ... } Blacklisting@Controller public class UserController { @InitBinder public void initBinder(WebDataBinder binder, WebRequest request) { binder.setDisallowedFields(["isAdmin"]); } ... } NodeJS + MongooseWhitelistingvar UserSchema = new mongoose.Schema({ userid : String, password : String, email : String, isAdmin : Boolean, }); UserSchema.statics = { User.userCreateSafeFields: ['userid', 'password', 'email'] }; var User = mongoose.model('User', UserSchema); _ = require('underscore'); var user = new User(_.pick(req.body, User.userCreateSafeFields)); Blacklistingvar massAssign = require('mongoose-mass-assign'); var UserSchema = new mongoose.Schema({ userid : String, password : String, email : String, isAdmin : { type: Boolean, protect: true, default: false } }); UserSchema.plugin(massAssign); var User = mongoose.model('User', UserSchema); /** Static method, useful for creation **/ var user = User.massAssign(req.body); /** Instance method, useful for updating **/ var user = new User; user.massAssign(req.body); /** Static massUpdate method **/ var input = { userid: 'bhelx', isAdmin: 'true' }; User.update({ '_id': someId }, { $set: User.massUpdate(input) }, console.log); Ruby On RailsDjangoASP.NETPHP Laravel + EloquentWhitelisting<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { private $userid; private $password; private $email; private $isAdmin; protected $fillable = array('userid','password','email'); } Blacklisting<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { private $userid; private $password; private $email; private $isAdmin; protected $guarded = array('isAdmin'); } GrailsPlayJackson (JSON Object Mapper)GSON (JSON Object Mapper)JSON-Lib (JSON Object Mapper)Flexjson (JSON Object Mapper)Authors and Primary EditorsReferences and future reading
Other Cheatsheets |