Difference between revisions of "Mass Assignment Cheat Sheet"

From OWASP
Jump to: navigation, search
Line 6: Line 6:
 
Last revision (mm/dd/yy): '''{{REVISIONMONTH}}/{{REVISIONDAY}}/{{REVISIONYEAR}}'''  
 
Last revision (mm/dd/yy): '''{{REVISIONMONTH}}/{{REVISIONDAY}}/{{REVISIONYEAR}}'''  
 
<div class="noautonum">__TOC__{{TOC hidden}}</div>
 
<div class="noautonum">__TOC__{{TOC hidden}}</div>
 +
  
 
= Introduction =
 
= Introduction =
 +
=== Definition ===
 
"Modern frameworks allow developers to automatically bind HTTP request parameters from both request query and body into model objects for ease of development and increased productivity. If the binder is not correctly configured to control which HTTP request parameters are bound to which model attributes, an attacker may be able to abuse the model binding process and set any other attributes that should not be exposed to user control. This binding is possible even if the model attributes do not appear in the web forms or API contracts." - [http://www.hpenterprisesecurity.com/vulncat/en/vulncat/java/mass_assignment_sensitive_field_exposure.html Mass Assignment: Sensitive Field Exposure]
 
"Modern frameworks allow developers to automatically bind HTTP request parameters from both request query and body into model objects for ease of development and increased productivity. If the binder is not correctly configured to control which HTTP request parameters are bound to which model attributes, an attacker may be able to abuse the model binding process and set any other attributes that should not be exposed to user control. This binding is possible even if the model attributes do not appear in the web forms or API contracts." - [http://www.hpenterprisesecurity.com/vulncat/en/vulncat/java/mass_assignment_sensitive_field_exposure.html Mass Assignment: Sensitive Field Exposure]
 +
 +
 +
=== Alternative Names ===
 +
Depending on the language/framework in question, this vulnerability can have several [https://cwe.mitre.org/data/definitions/915.html alternative names]
 +
* Mass Assignment: Ruby on Rails, NodeJS
 +
* Autobinding: Spring MVC, ASP.NET MVC
 +
* Object injection: PHP
 +
  
 
=== Example ===
 
=== Example ===
Line 54: Line 64:
 
   userid=bobbytables&password=hashedpass&email=bobby@tables.com&isAdmin=true
 
   userid=bobbytables&password=hashedpass&email=bobby@tables.com&isAdmin=true
  
 +
 +
=== Exploitability ===
  
 
The attacker can exploit this if:
 
The attacker can exploit this if:
 
* They can guess common sensitive fields
 
* They can guess common sensitive fields
* They have access to source code and review the models for sensitive fields
+
* They have access to source code and can review the models for sensitive fields
 +
* The object with sensitive fields has an empty constructor
 +
 
 +
 
 +
=== Case Studies ===
 +
==== GitHub ====
 +
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. [https://github.com/blog/1068-public-key-security-vulnerability-and-mitigation GitHub's Blog Post]
 +
 
  
=== General Solutions ===
+
=== Solutions ===
 
* Whitelist the bindable, non-sensitive fields
 
* Whitelist the bindable, non-sensitive fields
 
* Blacklist the non-bindable, sensitive fields
 
* Blacklist the non-bindable, sensitive fields
 
* Use Data Transfer Objects (DTOs)
 
* Use Data Transfer Objects (DTOs)
  
=== Alternative Names ===
 
Depending on the language/framework in question, this vulnerability can have several [https://cwe.mitre.org/data/definitions/915.html alternative names]
 
* Mass Assignment: Ruby on Rails, NodeJS
 
* Autobinding: Spring MVC, ASP.NET MVC
 
* Object injection: PHP
 
  
 +
= General Solutions =
 +
=== Data 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 UserDTO {
 +
      private String userid;
 +
      private String password;
 +
      private String email;
 +
 
 +
      //private boolean isAdmin;
 +
   
 +
      //Getters & Setters
 +
    }
  
= Languages & Frameworks =
+
= Language & Framework Specific Solutions =
  
 
== Spring MVC ==
 
== Spring MVC ==
Line 104: Line 131:
 
[http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/DataBinder.html#setDisallowedFields-java.lang.String...- Reference]
 
[http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/DataBinder.html#setDisallowedFields-java.lang.String...- Reference]
  
== NodeJS ==
+
== NodeJS + Mongoose ==
 +
 
 +
[https://www.npmjs.com/package/mongoose-mass-assign Reference]
  
 
== Ruby On Rails ==
 
== Ruby On Rails ==
 +
 +
[http://guides.rubyonrails.org/v3.2.9/security.html#mass-assignment Reference]
  
 
== Django ==  
 
== Django ==  
 +
 +
[https://coffeeonthekeyboard.com/mass-assignment-security-part-10-855/ Reference]
  
 
== ASP.NET ==
 
== ASP.NET ==
 +
 +
[http://odetocode.com/Blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx Reference]
  
 
== PHP Laravel + Eloquent ==
 
== PHP Laravel + Eloquent ==
Line 152: Line 187:
  
 
[https://laravel.com/docs/5.2/eloquent#mass-assignment Reference]
 
[https://laravel.com/docs/5.2/eloquent#mass-assignment Reference]
 +
 +
== Grails ==
 +
[http://spring.io/blog/2012/03/28/secure-data-binding-with-grails/ Reference]
  
 
= Authors and Primary Editors =
 
= Authors and Primary Editors =

Revision as of 17:57, 17 February 2016

Cheatsheets-header.jpg

Last revision (mm/dd/yy): 02/17/2016


Introduction

Definition

"Modern frameworks allow developers to automatically bind HTTP request parameters from both request query and body into model objects for ease of development and increased productivity. If the binder is not correctly configured to control which HTTP request parameters are bound to which model attributes, an attacker may be able to abuse the model binding process and set any other attributes that should not be exposed to user control. This binding is possible even if the model attributes do not appear in the web forms or API contracts." - Mass Assignment: Sensitive Field Exposure


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:

  <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=bobby@tables.com

And here is the exploit:

  POST /addUser
  
  userid=bobbytables&password=hashedpass&email=bobby@tables.com&isAdmin=true


Exploitability

The attacker can exploit this if:

  • They can guess common sensitive fields
  • They have access to source code and can review the models for sensitive fields
  • The object with sensitive fields has an empty constructor


Case Studies

GitHub

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

Data 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 UserDTO {
     private String userid;
     private String password;
     private String email;
  
     //private boolean isAdmin;
   
     //Getters & Setters
   }

Language & Framework Specific Solutions

Spring MVC

Whitelisting

  @Controller
  public class UserController
  {
     @InitBinder
     public void initBinder(WebDataBinder binder, WebRequest request)
     {
        binder.setAllowedFields(["userid","password","email"]);
     }
  
     ...
  }

Reference

Blacklisting

  @Controller
  public class UserController
  {
     @InitBinder
     public void initBinder(WebDataBinder binder, WebRequest request)
     {
        binder.setDisallowedFields(["isAdmin"]);
     }
  
     ...
  }

Reference

NodeJS + Mongoose

Reference

Ruby On Rails

Reference

Django

Reference

ASP.NET

Reference

PHP Laravel + Eloquent

Whitelisting

  <?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');
  
  }

Reference

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');
  
  }

Reference

Grails

Reference

Authors and Primary Editors

References and future reading

Other Cheatsheets