Missing Authentication in Django with Bearer Tokens
Missing Authentication in Django with Bearer Tokens
Missing authentication in a Django API that uses Bearer tokens occurs when protected endpoints do not validate the presence or correctness of the Authorization header. This creates an unauthenticated attack surface that can be discovered by a black-box scan such as one performed by middleBrick, which tests the endpoint without credentials. When authentication is absent or misconfigured, any unauthenticated request can access resources or invoke actions that should be restricted, leading to potential data exposure or unauthorized operations.
In Django, developers commonly use packages like django-rest-framework-simplejwt or custom token-based schemes to issue Bearer tokens. A token is typically sent in the HTTP Authorization header as Authorization: Bearer <token>. If the view or viewset does not enforce permission classes that verify this header, the request proceeds as if the user is authenticated with valid privileges. For example, consider a view that lists sensitive user profiles:
from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.models import UserProfile
class UserProfileList(APIView):
# Danger: No permission or authentication classes applied
def get(self, request):
profiles = UserProfile.objects.all().values('id', 'email', 'phone')
return Response(list(profiles))
In this snippet, no authentication or permission classes are set, so any request to this endpoint—regardless of whether a Bearer token is provided—will succeed. A scanner testing unauthenticated endpoints will flag this as a missing authentication issue. Even if authentication middleware exists globally, if a view explicitly overrides permission classes with permission_classes = [] or omits them entirely, the vulnerability remains. This is especially risky when the endpoint exposes PII or internal data, as it would be flagged by middleBrick’s Data Exposure and Authentication checks.
Another common pattern is using token authentication but failing to enforce it on specific routes. For instance, a developer might configure a default authentication class for the project but neglect to apply it to a newly added endpoint:
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
# urls.py
from django.urls import path
from myapp.views import UserProfileList
urlpatterns = [
path('profiles/', UserProfileList.as_view()), # Inherits auth from settings
]
This configuration works only if the project consistently relies on global defaults. If a later change removes or overrides the defaults, the endpoint becomes exposed. middleBrick’s Authentication check tests whether endpoints require credentials in practice, not just in configuration, revealing such gaps.
Bearer Tokens-Specific Remediation in Django
To remediate missing authentication with Bearer tokens in Django, explicitly enforce token validation on every endpoint that requires protection. The most reliable approach is to combine Django REST Framework’s TokenAuthentication with the IsAuthenticated permission class at the view or viewset level. This ensures the server rejects requests that lack a valid Bearer token or provide an invalid one.
Here is a secure example using function-based views:
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def secure_user_list(request):
profiles = UserProfile.objects.all().values('id', 'email', 'phone')
return Response(list(profiles))
For class-based views, apply the decorators or set class attributes:
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
class SecureUserProfileList(APIView):
def get(self, request):
profiles = UserProfile.objects.all().values('id', 'email', 'phone')
return Response(list(profiles))
When using viewsets, configure the attributes directly on the class:
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from myapp.models import UserProfile
from myapp.serializers import UserProfileSerializer
class UserProfileViewSet(viewsets.ReadOnlyModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
Additionally, ensure that tokens are transmitted securely over HTTPS to prevent interception. The Bearer token scheme relies on the confidentiality of the token; without transport-layer encryption, tokens can be captured and reused. middleBrick’s Encryption check can identify endpoints served over unencrypted or misconfigured TLS channels.
Finally, validate tokens on the server side and avoid accepting tokens from untrusted sources. If you use a custom token format, ensure it is verified against your database or an identity provider. The combination of explicit authentication classes, secure transport, and token integrity checks reduces the risk of unauthorized access and helps your API achieve a strong security score in assessments conducted by tools like middleBrick.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |