HIGH mass assignmentdjangobearer tokens

Mass Assignment in Django with Bearer Tokens

Mass Assignment in Django with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Mass Assignment occurs when a Django API binds incoming request data directly to a model or serializer without explicit field allowlisting. When endpoints accept Bearer Tokens for authentication but still rely on permissive data binding (for example, using a model’s save() or a serializer’s .create() with request.data), attackers can inject fields they should not control, such as is_staff, role, or permissions. This is a BOLA/IDOR and BFLA/Privilege Escalation risk: even though authentication is present (Bearer Token), authorization is weak because the server implicitly trusts client-supplied keys.

Consider a typical pattern that appears vulnerable:

class Task(models.Model):
    title = models.CharField(max_length=200)
    completed = models.BooleanField(default=False)
    is_internal = models.BooleanField(default=False)  # privileged field
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

An endpoint that does not restrict fields can be abused:

def update_task(request, task_id):
    task = Task.objects.get(id=task_id)
    # Unsafe: mass assignment with Bearer Token authentication
    for key, value in request.data.items():
        setattr(task, key, value)
    task.save()
    return JsonResponse({'status': 'ok'})

Even when the client presents a valid Bearer Token, the server allows the client to set is_internal or change the owner by including those keys in JSON. This maps to OWASP API Top 10:01 (Broken Object Level Authorization) and 05 (Mass Assignment). In a black-box scan, middleBrick tests such scenarios by submitting payloads that attempt to escalate privileges via unchecked fields, and it flags these as high-severity findings.

Another common exposure is using Django REST Framework’s ModelSerializer with .create() or .update() while passing request.data without fields restriction:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'  # risky: includes privileged fields

If the API relies on Bearer Tokens for auth but does not enforce field-level authorization, the broad fields = '__all__' enables privilege escalation. middleBrick’s checks for Property Authorization and BFLA will surface this by probing endpoints with role-modifying payloads and observing whether unauthorized changes persist.

Bearer Tokens-Specific Remediation in Django — concrete code fixes

Remediation focuses on explicit field allowlisting and ensuring authorization checks are independent of authentication. Do not bind request.data directly; instead, specify which fields can be updated per role. Combine token-based authentication with view- or method-level permission checks.

1) Use serializer fields or extra_kwargs to restrict writable fields per action:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['title', 'completed']
        read_only_fields = ['is_internal', 'owner']

2) Enforce ownership and privilege checks in the view. Even with a Bearer Token, ensure the requesting user can only modify their own non-sensitive fields:

from rest_framework.permissions import BasePermission

class IsOwnerOrReadOnly(BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in ('GET', 'OPTIONS'):
            return True
        return obj.owner == request.user

def update_task_secure(request, task_id):
    task = Task.objects.get(id=task_id)
    # Permission: Bearer Token identifies request.user; scope limits to safe fields
    if not IsOwnerOrReadOnly().has_object_permission(request, None, task):
        return JsonResponse({'error': "forbidden"}, status=403)
    # Safe: only allow known-safe fields
    safe_data = {k: v for k, v in request.data.items() if k in {'title', 'completed'}}
    for key, value in safe_data.items():
        setattr(task, key, value)
    task.save()
    return JsonResponse({'status': 'ok'})

3) For token-based APIs, validate tokens early (e.g., via DRF’s authentication classes) and bind claims to the request user, then apply per-field authorization in serializers:

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class BearerTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        auth = request.headers.get('Authorization')
        if not auth or not auth.startswith('Bearer '):
            return None
        token = auth.split(' ')[1]
        # Validate token and fetch user (pseudocode)
        user = validate_bearer_token(token)  # implement your validation
        if not user:
            raise AuthenticationFailed('Invalid token')
        return (user, None)

4) In DRF views, prefer .update() with explicit fields and avoid setattr loops over raw request.data. Use partial updates safely:

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    authentication_classes = [BearerTokenAuthentication]
    permission_classes = [IsOwnerOrReadOnly]

    def update(self, request, *args, **kwargs):
        # Only fields defined in TaskSerializer are honored
        return super().update(request, *args, **kwargs)

These steps ensure that Bearer Token authentication does not inadvertently enable mass assignment: authentication confirms identity, while explicit field control and ownership checks enforce authorization.

Related CWEs: propertyAuthorization

CWE IDNameSeverity
CWE-915Mass Assignment HIGH

Frequently Asked Questions

Does using Bearer Tokens alone prevent mass assignment in Django APIs?
No. Bearer Tokens handle authentication (who you are) but do not enforce authorization (what you may change). Without explicit field allowlisting, mass assignment remains possible regardless of token presence.
How does middleBrick detect mass assignment risks when Bearer Tokens are used?
middleBrick runs black-box checks that submit payloads containing privileged fields (e.g., is_internal, role) even when a valid Bearer Token is provided. If these fields alter server state without authorization checks, the scan reports a high-severity finding for BOLA/IDOR and BFLA/Privilege Escalation.