# Mass Assignment

Many web-frameworks automate the process of assigning parameters from an incoming HTTP request to the fields on an in-memory object. You need to ensure that you are using assignment logic in your code in such a way that only permitted fields are written to. Otherwise, an attacker can perform a **mass assignment** attack, overwriting sensitive data fields (like permissions and roles) they should not be able to access.

## Mass Assignment in Python

A common design pattern is to take data from an HTTP request – either the HTTP parameters or from JSON or XML in the body of the request – and to update the contents of an object in-memory or in the database. In Python, this design pattern in often achieved by using the `setattr(…)` function:

class User(models.Model):
(‘G’, ‘Guest’),
(‘U’, ‘User’),
(‘A’, ‘Admin’),
(‘S’, ‘Superuser’)
)id = models.IntegerField()
username = models.CharField(max_length=100)
email = models.CharField(max_length=100)
password = models.CharField(max_length=100)
role = models.CharField(max_length=1, choices=ROLES)
updated = models.DateTimeField()

def profile(request):
“””View or update the user’s profile.”””
user = get_current_user()

if user is None:
return HttpResponseRedirect(‘/login’)

if request.method == ‘POST’:
data = json.loads(request.body)

# Danger: updating arbitrary fields on the user object from incoming JSON is dangerous!
for key, value in data.items():
setattr(user, key, value)

user.updated = datetime.now()

return HttpResponse(“Profile updated”, 202)

elif request.method == ‘GET’:
return render(request, ‘profile.html’, { ‘user’: user })

return HttpResponseNotAllowed((‘GET’, ‘POST’))

This code is vulnerable to a *mass assignment* attack since the function allows the user to change anything in their profile – and specifically, it allows a user to change their role. Even if the `role` is not sent by client-side JavaScript code, an attacker can send their own JSON request that contains the extra field, and hence make themselves an administrator.

When mapping uploaded data to objects, *only* enumerate properties that you intend to be editable:

if request.method == ‘POST’:
data = json.loads(request.body)# Explicitly enumerating the fields to be updated protects us from mass-assignment.
user.email = data.get(’email’, user.email)
user.username = data.get(‘username’, user.username)

user.updated = datetime.now()

return HttpResponse(“Profile updated”, 202)

## CWEs

* [CWE-915](https://cwe.mitre.org/data/definitions/915.html)

About ShiftLeft

ShiftLeft empowers developers and AppSec teams to dramatically reduce risk by quickly finding and fixing the vulnerabilities most likely to reach their applications and ignoring reported vulnerabilities that pose little risk. Industry-leading accuracy allows developers to focus on security fixes that matter and improve code velocity while enabling AppSec engineers to shift security left.

A unified code security platform, ShiftLeft CORE scans for attack context across custom code, APIs, OSS, containers, internal microservices, and first-party business logic by combining results of the company’s and Intelligent Software Composition Analysis (SCA). Using its unique graph database that combines code attributes and analyzes actual attack paths based on real application architecture, ShiftLeft then provides detailed guidance on risk remediation within existing development workflows and tooling. Teams that use ShiftLeft ship more secure code, faster. Backed by SYN Ventures, Bain Capital Ventures, Blackstone, Mayfield, Thomvest Ventures, and SineWave Ventures, ShiftLeft is based in Santa Clara, California. For information, visit: www.shiftleft.io.


See for yourself – run a scan on your code right now