HIGH ssrfdjangobasic auth

Ssrf in Django with Basic Auth

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

Server-Side Request Forgery (SSRF) in Django when Basic Authentication is used centers on how HTTP requests are issued from the server. Basic Auth credentials are often embedded in request headers or a request’s Authorization field before the call leaves the application. If an attacker can influence the target URL or headers of these outbound requests, they can direct the server to an internal endpoint, such as the metadata service at http://169.254.169.254 or a local admin interface, while the request carries Basic Auth credentials that the application trusts. This combination exposes internal services because the server-side code makes authenticated outbound calls to user-supplied locations.

Consider a view that fetches a remote resource and passes along stored credentials:

import requests
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET"])
def fetch_external_data(request):
    url = request.GET.get("url")
    username = "admin"
    password = "secret"
    if not url:
        return JsonResponse({"error": "url parameter required"}, status=400)
    try:
        resp = requests.get(url, auth=(username, password), timeout=5)
        return JsonResponse({"status_code": resp.status_code, "content_length": len(resp.content)})
    except requests.RequestException as e:
        return JsonResponse({"error": str(e)}, status=502)

In this pattern, the URL is user-controlled, and the request carries Basic Auth. An attacker can supply a URL pointing to an internal service (e.g., http://127.0.0.1:8000/admin or a cloud metadata endpoint), and the server will relay credentials to that target. Because the scanning performed by middleBrick tests unauthenticated attack surfaces, it can surface endpoints where SSRF is possible even when the application uses Basic Auth for inbound requests; the risk is not that Basic Auth is bypassed inbound, but that outbound authenticated requests become a pivot.

Additionally, if the Django application uses a session or a token obtained via Basic Auth to further authorize outbound calls, SSRF can lead to unintended access to internal APIs or metadata stores. The presence of Basic Auth does not mitigate SSRF; it can amplify impact by ensuring the forged request succeeds against protected internal endpoints. Detection involves correlating user input in URL parameters or headers with outbound network calls while ensuring that request logic does not implicitly trust credentials stored in code or environment variables.

Basic Auth-Specific Remediation in Django — concrete code fixes

Remediation focuses on removing or strictly limiting the ability for user input to influence outbound authenticated requests. Avoid passing Basic Auth credentials to arbitrary URLs, and validate or restrict target hosts. Below are concrete, safe patterns.

1. Do not forward Basic Auth to user-supplied URLs

Remove the auth parameter when the target URL is not fully controlled and trusted. If you must call external services, use a service account with minimal permissions and avoid embedding credentials in code.

import requests
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

ALLOWED_HOSTS = {"api.example.com", "data.example.com"}

@require_http_methods(["GET"])
def safe_fetch_external_data(request):
    url = request.GET.get("url")
    if not url:
        return JsonResponse({"error": "url parameter required"}, status=400)
    # Validate host against an allowlist
    from urllib.parse import urlparse
    host = urlparse(url).hostname or ""
    if host not in ALLOWED_HOSTS:
        return JsonResponse({"error": "host not allowed"}, status=403)
    try:
        # No auth forwarded to user-controlled target
        resp = requests.get(url, timeout=5)
        return JsonResponse({"status_code": resp.status_code, "content_length": len(resp.content)})
    except requests.RequestException as e:
        return JsonResponse({"error": str(e)}, status=502)

2. Use environment-based credentials with strict destination controls

If outbound calls must carry credentials, do not derive the target from user input. Instead, select a predefined, internal endpoint and keep credentials out of dynamic URL assembly.

import os
import requests
from django.http import JsonResponse

OUTBOUND_URL = os.getenv("OUTBOUND_SERVICE_URL", "https://api.example.com/collect")
USERNAME = os.getenv("OUTBOUND_USER")
PASSWORD = os.getenv("OUTBOUND_PASS")

def post_to_fixed_endpoint(data):
    if not USERNAME or not PASSWORD:
        raise ValueError("Missing outbound credentials")
    resp = requests.post(OUTBOUND_URL, auth=(USERNAME, PASSWORD), json=data, timeout=5)
    resp.raise_for_status()
    return resp.json()

3. Use session-based or token-based auth selectively

When you need to call a known internal API, use short-lived tokens scoped to that service rather than long-lived Basic credentials. Validate the token scope and audience before use.

import requests
from django.http import JsonResponse

def call_trusted_service(token, payload):
    headers = {"Authorization": f"Bearer {token}"}
    resp = requests.post("https://internal.service.example.com/ingest", headers=headers, json=payload, timeout=5)
    resp.raise_for_status()
    return resp.json()

These patterns ensure that user-controlled input cannot redirect authenticated outbound traffic to arbitrary internal endpoints, which is the core of SSRF in this context.

Related CWEs: ssrf

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

Frequently Asked Questions

Does Basic Auth in Django prevent SSRF if the endpoint requires authentication?
No. Basic Auth in Django secures inbound requests to your app. SSRF arises from outbound requests that the server makes to user-supplied URLs while including credentials; the authentication on inbound does not stop the server from forwarding credentials to internal or malicious endpoints.
Can middleBrick detect SSRF in a Django app that uses Basic Auth?
Yes. middleBrick tests the unauthenticated attack surface and can identify SSRF by probing endpoints that accept URLs as input and make outbound calls, even when those calls include Basic Auth headers.