# Improperly Controlled Modification of Dynamically-Determined Object Attributes (CWE-915) The product receives input from an upstream component that specifies multiple attributes, properties, or fields that are to be initialized or updated in an object, but it does not properly control which attributes can be modified. - Prevalence: High Frequently exploited - Impact: Critical 2 critical-severity rules - Prevention: Documented 5 fix examples **OWASP:** Injection (A03:2021-Injection) - #3 ## Description If the object contains attributes that are not intended to be modified, then an attacker can use the vulnerability to overwrite critical application values, gain privileges, or bypass security checks. ## Prevention Prevention strategies for Mass Assignment based on 5 Shoulder detection rules. ### Python Use ModelForm with explicit fields whitelist instead of **kwargs or exclude Whitelist allowed attributes before using setattr() or __dict__.update() Use explicit field lists in serializers and mark privilege fields as read-only ### Node.js Validate input with Zod schema and use explicit field assignment instead of spreading req.body Use explicit field assignment or class-transformer with excludeExtraneousValues instead of spreading req.body ## Warning Signs - [HIGH] Django code that creates or updates models using all request data without validation - [HIGH] unsafe modification of class attributes or object __dict__ using user input - [HIGH] serializers or forms that expose privilege-related fields without marking them as read-only - [CRITICAL] ... uses unvalidated user input in data parameter. Use explicit field whitelisting with validation. - [CRITICAL] Entity properties assigned directly from user input without whitelisting. This allows unauthorized field modification. ## Consequences - Gain Privileges - Bypass Protection Mechanism - Modify Application Data ## Mitigations - Use an allowlist of permitted attributes for mass assignment - Implement proper input validation to reject unexpected attributes - Use Data Transfer Objects (DTOs) to control which fields can be modified ## Detection - Total rules: 5 - Critical: 2 - Languages: python, javascript, typescript ## Rules by Language ### Python (3 rules) - **Django Mass Assignment Vulnerability** [HIGH]: Detects Django code that creates or updates models using all request data without validation. This allows attackers to set arbitrary fields including sensitive ones like is_admin, is_staff, or permissions. NOTE: This rule only flags POST/PUT/PATCH request body data (request.POST, request.data). It does NOT flag request.GET or request.query_params, as those are typically used for read-only filtering operations and cannot cause mass assignment vulnerabilities in standard Django ORM usage. - Remediation: Use ModelForm with explicit fields to whitelist allowed attributes. ```python from django import forms from .models import User class UserForm(forms.ModelForm): class Meta: model = User fields = ['username', 'email', 'bio'] def create_user(request): form = UserForm(request.POST) if form.is_valid(): form.save() ``` Learn more: https://shoulder.dev/learn/python/cwe-915/mass-assignment - **Class/Attribute Pollution** [HIGH]: Detects unsafe modification of class attributes or object __dict__ using user input. - Remediation: Whitelist allowed attributes before using setattr. ```python ALLOWED_ATTRS = {"username", "email"} if key in ALLOWED_ATTRS: setattr(user, key, value) ``` Learn more: https://shoulder.dev/learn/python/cwe-915/class-pollution - **Serializer/Form Exposes Privilege Fields** [HIGH]: Detects serializers or forms that expose privilege-related fields without marking them as read-only. - Remediation: Use explicit field lists and mark privilege fields as read-only. ```python class Meta: fields = ['username', 'email'] read_only_fields = ['is_staff', 'is_superuser'] ``` Learn more: https://shoulder.dev/learn/python/cwe-915/serializer-privilege-exposure ### Javascript (2 rules) - **Prisma Mass Assignment Vulnerability** [CRITICAL]: Spreading req.body into Prisma create/update allows attackers to modify protected fields like role, credits, or permissions. - Remediation: Use explicit field assignment instead of spreading req.body. ```typescript const input = createUserSchema.parse(req.body); const user = await prisma.user.create({ data: { email: input.email, name: input.name // role not assigned from user input } }); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-915/prisma-mass-assignment - **TypeORM Mass Assignment Vulnerability** [CRITICAL]: Directly assigning req.body to entities allows attackers to modify protected fields like role, isAdmin, or credits. - Remediation: Use explicit field assignment instead of spreading request data. ```typescript const user = repository.create({ username: req.body.username, email: req.body.email // role and isAdmin not assigned from user input }); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-915/mass-assignment ### Typescript (2 rules) - **Prisma Mass Assignment Vulnerability** [CRITICAL]: Spreading req.body into Prisma create/update allows attackers to modify protected fields like role, credits, or permissions. - Remediation: Use explicit field assignment instead of spreading req.body. ```typescript const input = createUserSchema.parse(req.body); const user = await prisma.user.create({ data: { email: input.email, name: input.name // role not assigned from user input } }); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-915/prisma-mass-assignment - **TypeORM Mass Assignment Vulnerability** [CRITICAL]: Directly assigning req.body to entities allows attackers to modify protected fields like role, isAdmin, or credits. - Remediation: Use explicit field assignment instead of spreading request data. ```typescript const user = repository.create({ username: req.body.username, email: req.body.email // role and isAdmin not assigned from user input }); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-915/mass-assignment