HIGH missing authenticationdjangobearer tokens

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 IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How does middleBrick detect missing authentication in unauthenticated scans?
middleBrick tests endpoints without credentials and examines whether the server enforces access control. It checks for missing or misconfigured permission classes and reports endpoints that return sensitive data without requiring a valid Bearer token.
Can relying only on global Django REST Framework settings prevent authentication bypass?
No. Global settings can be inadvertently overridden by individual views or viewsets. Explicitly setting authentication_classes and permission_classes on each endpoint ensures consistent enforcement and prevents accidental exposure.