HIGH path traversaldjangodynamodb

Path Traversal in Django with Dynamodb

Path Traversal in Django with Dynamodb — how this specific combination creates or exposes the vulnerability

Path Traversal occurs when user input is used to construct file system paths without proper validation, allowing an attacker to access files outside the intended directory. In a Django application using Amazon DynamoDB as a backend, the risk typically arises at the application layer rather than in DynamoDB itself, because DynamoDB does not operate with a traditional file system path model. However, misconfigured data access patterns in Django can lead to unsafe handling of object keys or metadata that indirectly reference sensitive files or configuration artifacts stored outside the DynamoDB tables.

Consider a Django view that retrieves user documents from DynamoDB based on a user-supplied identifier, such as a file key. If the developer directly interpolates this key into a path used for secondary operations—such as generating pre-signed URLs, writing logs, or referencing local cache files—an attacker may supply sequences like ../../../etc/passwd to traverse directories. Even though DynamoDB stores data in a managed NoSQL table, the surrounding Django code might use the key to access associated resources on the server’s filesystem, for example when caching query results or constructing dynamic redirects. This creates a path traversal surface if input validation is weak or absent.

Moreover, DynamoDB’s primary key structure, which includes partition and sort keys, can inadvertently mirror directory-like hierarchies (e.g., user/123/report). If Django code naively maps these key components to local paths—such as storing exported reports under a user-specific folder—without canonicalizing or restricting the resulting path, an attacker may manipulate key values to traverse outside the intended directory scope. For instance, a sort key like ../../../secrets/config.json could be injected if input sanitization is not enforced before using the key in local filesystem operations.

The combination of Django’s flexible request handling and DynamoDB’s key-based model increases risk when developers treat database keys as safe filesystem proxies. The scanner checks for these patterns by analyzing the unauthenticated attack surface and correlating OpenAPI specifications with runtime behavior, flagging endpoints where user-controlled input influences local resource references, even if the data ultimately resides in DynamoDB.

Dynamodb-Specific Remediation in Django — concrete code fixes

To mitigate path traversal in Django when working with DynamoDB, focus on strict input validation, canonicalization, and avoiding filesystem operations based on database keys. Below are concrete remediation steps and code examples.

1. Validate and sanitize key inputs

Ensure that any user input used to construct DynamoDB keys or related paths is strictly validated. Use Django forms or serializers to enforce allowed character sets and reject potentially dangerous sequences.

import re
from django import forms

class DocumentKeyForm(forms.Form):
    user_id = forms.CharField(max_length=128)
    doc_key = forms.CharField(max_length=256)

    def clean_doc_key(self):
        key = self.cleaned_data['doc_key']
        # Allow only alphanumeric, underscores, and hyphens
        if not re.match(r'^[a-zA-Z0-9_\-]+$', key):
            raise forms.ValidationError('Invalid key format')
        # Reject path traversal sequences
        if '..' in key or key.startswith('/'):
            raise forms.ValidationError('Invalid key: path traversal detected')
        return key

2. Use DynamoDB attribute values directly, not as filesystem paths

Avoid using DynamoDB key attributes to build local file paths. Instead, reference data by key within application logic. If you must generate external references, use pre-signed URLs provided by AWS SDK without concatenating user input into filesystem paths.

import boto3
from django.conf import settings

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table(settings.DYNAMODB_TABLE)

def get_object_key(user_id, doc_key):
    # Validate inputs before use
    response = table.get_item(
        Key={
            'user_id': user_id,
            'doc_key': doc_key
        }
    )
    item = response.get('Item')
    if item:
        # Generate a safe pre-signed URL without filesystem path construction
        s3_client = boto3.client('s3')
        url = s3_client.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': settings.AWS_STORAGE_BUCKET_NAME,
                'Key': item['s3_key']  # Use server-side key, not user input
            },
            ExpiresIn=3600
        )
        return url
    return None

3. Isolate filesystem operations from database keys

If your Django application must interact with local files, ensure that paths are constructed from trusted constants or configuration, never directly from user-supplied or database-derived values. Use os.path.realpath and os.path.commonprefix to enforce directory boundaries.

import os
from django.core.files.storage import FileSystemStorage

def safe_file_access(base_dir, requested_name):
    # Resolve absolute path and ensure it remains within base_dir
    target_path = os.path.realpath(os.path.join(base_dir, requested_name))
    if os.path.commonprefix([target_path, os.path.realpath(base_dir)]) != os.path.realpath(base_dir):
        raise ValueError('Path traversal attempt detected')
    # Proceed with safe file operations
    fs = FileSystemStorage(location=target_path)
    return fs

4. Leverage middleware for global input checks

Implement Django middleware to sanitize incoming paths across all views, rejecting requests containing traversal patterns before they reach business logic.

from django.http import HttpResponseBadRequest

class PathTraversalProtectionMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Check query parameters and path info for traversal patterns
        for key, value in request.GET.items():
            if '..' in value or value.startswith('/'):
                return HttpResponseBadRequest('Invalid input')
        response = self.get_response(request)
        return response

By combining strict validation, safe use of DynamoDB key structures, and isolation of filesystem operations, you reduce the attack surface while maintaining compatibility with Django and AWS services.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can DynamoDB key structures themselves cause path traversal?
DynamoDB keys do not directly cause path traversal because they are stored as attribute values, not filesystem paths. Risk emerges when Django code maps these keys to local paths or URLs without validation.
Does middleBrick detect path traversal in Django-Dynamodb setups?
Yes, middleBrick scans the unauthenticated attack surface and flags endpoints where user-controlled input could influence local resource references, including patterns that may affect DynamoDB key usage in Django.