HIGH symlink attackdjangobearer tokens

Symlink Attack in Django with Bearer Tokens

Symlink Attack in Django with Bearer Tokens — how this specific combination creates or exposes the vulnerability

A symlink attack in Django involving Bearer tokens typically occurs when file uploads or user-controlled paths are handled in a way that allows an attacker to place a symbolic link that points to a sensitive location such as a token storage directory. If your Django application exposes an endpoint that accepts file uploads and stores files based on user input without proper path validation, an authenticated attacker with a Bearer token could manipulate the upload path to create a symlink on the server. When the application later writes a file (for example, a token refresh file, session cache, or configuration artifact) to what it believes is a safe directory, the write is redirected to a location the attacker can read or overwrite.

Bearer tokens are often stored in headers and passed to Django views for authentication. If a view also performs file operations based on request parameters or user-controlled data, the combination of token-based authentication and unsafe file handling increases risk: the token proves identity but does not enforce authorization on file system operations. Consider a scenario where an authenticated client calls an endpoint like /upload/, and the server uses a user-supplied filename or directory to determine where to save the uploaded content. Without canonicalizing paths and ensuring the target resides within an allowed directory, an attacker can supply a filename such as ../../../secrets/token_backup or craft a symlink during upload that points outside the intended storage area.

In practice, this can expose token material if the application writes logs, caches, or temporary files containing tokens to the redirected location, or if the attacker replaces a legitimate file that the application later reads when processing authenticated requests. Because the attack leverages the trust the application places in user input rather than the token itself, the presence of a valid Bearer token is simply the means by which the attacker reaches the vulnerable code path. The vulnerability is not in how tokens are transmitted or stored in headers, but in how the server uses those authenticated sessions to perform unsafe file system actions.

Bearer Tokens-Specific Remediation in Django — concrete code fixes

To mitigate symlink risks while using Bearer tokens in Django, focus on strict input validation, path canonicalization, and isolation of file operations from authentication logic. Always resolve paths with os.path.realpath or Path.resolve(strict=True) and ensure the final path is within an allowed base directory. Avoid using user input directly to derive filesystem paths, and prefer generating server-side filenames.

Example of unsafe file handling that can lead to symlink issues:

import os
from django.http import JsonResponse

def unsafe_upload(request):
    # WARNING: This is vulnerable to path traversal and symlink attacks
    filename = request.GET.get('filename', 'upload.txt')
    upload_dir = '/var/app/uploads'
    destination = os.path.join(upload_dir, filename)
    with open(destination, 'wb') as f:
        f.write(request.body)
    return JsonResponse({'status': 'ok'})

Secure alternative using path validation and server-side naming:

import os
import uuid
from pathlib import Path
from django.http import JsonResponse

BASE_DIR = Path('/var/app/uploads').resolve()

def secure_upload(request):
    # Use a server-generated filename to avoid user-controlled paths
    ext = '.bin'  # derive or enforce a safe extension
    safe_name = f'{uuid.uuid4().hex}{ext}'
    destination = (BASE_DIR / safe_name).resolve()
    # Ensure the resolved path is still inside the allowed directory
    if not str(destination).startswith(str(BASE_DIR) + os.sep):
        return JsonResponse({'error': 'Invalid path'}, status=400)
    destination.write_bytes(request.body)
    return JsonResponse({'filename': safe_name})

If you must accept a filename, normalize and validate it rigorously:

from pathlib import Path
import os

def normalize_filename(user_name: str) -> str:
    p = Path(user_name).resolve()
    # Ensure the resolved path does not escape the base directory
    base = Path('/var/app/uploads').resolve()
    try:
        p.relative_to(base)
    except ValueError:
        raise ValueError('Path traversal detected')
    return str(p)

For Bearer token usage, keep token handling separate from file operations. Authenticate via token in middleware, but do not allow request-derived paths to influence where authenticated sessions write files. If you integrate middleBrick in your pipeline, you can add API security checks to CI/CD to catch such misconfigurations before deployment.

Frequently Asked Questions

Can a symlink attack read Bearer tokens from Django settings files?
Yes, if an attacker can trick the application into writing or replacing a file that points via symlink to a location where tokens are stored (for example, a configuration or cache directory), they may read or overwrite token material. Mitigate by isolating file operations from authentication and validating all paths.
Does using Bearer tokens in headers change how Django handles file uploads securely?
Bearer tokens in headers do not inherently affect file handling security. The risk comes from how the application uses request data to build filesystem paths. Always validate and sanitize paths independently of the authentication method.