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 ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |