HIGH ssrfdjangodynamodb

Ssrf in Django with Dynamodb

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

Server-Side Request Forgery (SSRF) in a Django application that interacts with Amazon DynamoDB typically arises when the app constructs HTTP requests to external services based on attacker-controlled data. If a Django endpoint accepts a URL or host parameter and uses it to query DynamoDB via the AWS SDK (boto3), an attacker can force the backend to make arbitrary internal or external requests. For example, an endpoint that fetches a DynamoDB table configuration from a user-provided URL may inadvertently allow probing of metadata service (169.254.169.254) or internal AWS endpoints.

The risk is amplified when the application uses IAM roles associated with the DynamoDB permissions. An SSRF vulnerability can lead to unintended AWS API calls, data leakage from DynamoDB tables, or lateral movement within the cloud environment. In a typical Django+boto3 setup, the application might call dynamodb.Table(table_name).get_item(Key=...) after retrieving the table name from an external source. If that external source is user input and not properly validated, an attacker can manipulate the flow to target sensitive DynamoDB endpoints or internal services.

Common patterns that lead to SSRF include using requests.get or urllib with user input to build URLs, misconfigured proxies, or insecure deserialization that passes URLs to AWS SDK calls. Because DynamoDB endpoints are internal to AWS and often reachable only from within the network, SSRF can expose metadata endpoints that provide temporary credentials, leading to privilege escalation. The Django context may include environment variables or configuration that reveal AWS regions, table names, or IAM role boundaries, which can be harvested via SSRF.

middleBrick detects SSRF as one of its 12 parallel security checks, identifying whether an endpoint allows forced internal requests to DynamoDB or AWS metadata services. The scanner tests for common SSRF indicators such as response differences when requesting http://169.254.169.254/latest/meta-data/ or internal AWS endpoints. Findings include severity, evidence, and remediation guidance mapped to frameworks like OWASP API Top 10 and SOC2.

Dynamodb-Specific Remediation in Django — concrete code fixes

To mitigate SSRF in Django when using DynamoDB, enforce strict input validation and avoid passing user-controlled data directly into AWS SDK calls. Use allowlists for table names and avoid dynamic URL construction. The following examples demonstrate secure patterns.

Secure DynamoDB Table Access

Instead of using user input to determine the table name, define a fixed mapping or use an allowlist. This prevents attackers from specifying arbitrary table names or endpoints.

import boto3
from django.conf import settings

ALLOWED_TABLES = {'users', 'profiles', 'settings'}

def get_dynamodb_table(table_name: str):
    if table_name not in ALLOWED_TABLES:
        raise ValueError('Invalid table name')
    return boto3.resource('dynamodb', region_name=settings.AWS_REGION)

def fetch_user_item(table_name: str, key: dict):
    table = get_dynamodb_table(table_name)
    response = table.Table(table_name).get_item(Key=key)
    return response.get('Item')

# Example usage in a Django view
from django.http import JsonResponse

def user_item_view(request, table_name):
    try:
        item = fetch_user_item(table_name, {'user_id': request.GET.get('user_id')})
        return JsonResponse(item or {})
    except ValueError as e:
        return JsonResponse({'error': str(e)}, status=400)

Avoiding Unsafe URL Usage

Never use user input to construct URLs for external requests. If your application requires fetching metadata, use predefined endpoints and validate all inputs.

import requests
from django.http import JsonResponse

SAFE_BASE_URL = 'https://api.example.com/v1/'

def safe_fetch(resource: str):
    if resource not in ['status', 'health']:
        raise ValueError('Invalid resource')
    url = SAFE_BASE_URL + resource
    resp = requests.get(url, timeout=5)
    resp.raise_for_status()
    return resp.json()

# Example view
from django.views import View

class HealthCheckView(View):
    def get(self, request):
        try:
            data = safe_fetch('status')
            return JsonResponse(data)
        except ValueError:
            return JsonResponse({'error': 'invalid resource'}, status=400)

Additional Hardening

  • Use IAM roles with minimal permissions for DynamoDB access and avoid broad policies.
  • Enable VPC endpoints for DynamoDB to restrict traffic to AWS internal networks.
  • Monitor and log AWS SDK calls using CloudTrail to detect anomalous requests originating from your Django app.

middleBrick can be integrated into your workflow via the CLI (middlebrick scan <url>), GitHub Action for CI/CD gates, or MCP Server for IDE-level scanning. Using these, you can automatically detect SSRF and other vulnerabilities before deployment.

Related CWEs: ssrf

CWE IDNameSeverity
CWE-918Server-Side Request Forgery (SSRF) CRITICAL
CWE-441Unintended Proxy or Intermediary (Confused Deputy) HIGH

Frequently Asked Questions

How can I test my Django API for SSRF using middleBrick?
Run middlebrick scan <your-api-url> from the terminal or integrate the GitHub Action to scan your staging endpoints. The report will flag SSRF findings with severity and remediation steps.
Does middleBrick provide compliance mappings for SSRF findings?
Yes, findings include mappings to OWASP API Top 10, PCI-DSS, SOC2, HIPAA, and GDPR where applicable, helping you align remediation with regulatory requirements.