HIGH ssrf server sidedjangofirestore

Ssrf Server Side in Django with Firestore

Ssrf Server Side in Django with Firestore — how this specific combination creates or exposes the vulnerability

Server-side request forgery (SSRF) in a Django application that uses Google Cloud Firestore can occur when the app builds Firestore client requests or HTTP calls using attacker-controlled input. For example, if user data is used to construct document paths, collection names, or Firestore query parameters without strict validation, an attacker may attempt to inject references that reach internal or unexpected endpoints. In environments where Firestore is accessed through service accounts and IAM rules, SSRF may not directly read Firestore resources, but it can enable metadata service access, internal network scanning, or SSRF-to-pivoting scenarios that escalate risk.

Django projects often integrate Firestore via the official Google Cloud client library. If the code passes user-supplied values into methods that determine which documents to read or write—such as document IDs, collection names, or custom query parameters—without canonicalization and strict allowlisting, the application may be tricked into issuing requests to internal IPs or metadata endpoints. For instance, an attacker might supply a document ID resembling a metadata service address, hoping the backend HTTP library (used by the Firestore client) follows redirects or makes internal calls. The Firestore client itself does not perform HTTP redirections to internal metadata services, but the surrounding Django app might make additional HTTP calls (e.g., fetching remote schemas or validating URLs) using the same tainted input, creating the SSRF vector.

Another vector involves Firestore’s support for custom endpoints. If the client is configured with a user-controlled host, an attacker can redirect traffic to an internal service. This misconfiguration is often paired with overly permissive IAM service account permissions in the hosting environment, allowing an SSRF-affected service account to query internal metadata or other Google Cloud services. Even when Firestore operations themselves are limited to permitted databases and collections, SSRF can expose sensitive metadata and open paths for lateral movement. Therefore, input validation, canonicalization, and restricting outbound destinations are essential to reduce the attack surface in this specific stack.

Firestore-Specific Remediation in Django — concrete code fixes

To mitigate SSRF in Django with Firestore, validate and sanitize all inputs that affect Firestore operations. Use strict allowlists for document IDs, collection names, and query parameters. Avoid constructing Firestore paths from raw user input. Prefer parameterized queries and explicit mapping instead of dynamic path assembly where possible. The following examples illustrate secure patterns.

Secure document ID handling

Validate document IDs against a regex allowlist before using them in Firestore lookups:

import re
from google.cloud import firestore
from django.http import HttpResponseBadRequest

def get_user_document(request, user_id):
    # Strict allowlist: alphanumeric and underscores, 1–64 chars
    if not re.match(r'^[A-Za-z0-9_]{1,64}$', user_id):
        return HttpResponseBadRequest('Invalid document ID')
    db = firestore.Client()
    doc_ref = db.collection('users').document(user_id)
    doc = doc_ref.get()
    if doc.exists:
        return doc.to_dict()
    return {'error': 'not found'}, 404

Parameterized collection and query usage

Avoid dynamic collection names derived from user input. If dynamic access is required, map to an allowlist:

ALLOWED_COLLECTIONS = {'public_posts', 'audit_logs'}

def fetch_from_collection(request, collection_name):
    if collection_name not in ALLOWED_COLLECTIONS:
        return HttpResponseBadRequest('Invalid collection')
    db = firestore.Client()
    docs = db.collection(collection_name).limit(10).stream()
    return [doc.to_dict() for doc in docs]

Safe URL and metadata handling

If your Django app uses Firestore alongside HTTP calls (e.g., fetching remote resources), ensure user input is not used to construct request URLs or redirect targets. Use a hardcoded allowlist of domains and a robust URL parser:

from urllib.parse import urlparse
import requests

def fetch_external_resource(url_str):
    parsed = urlparse(urlstr)
    if parsed.scheme not in ('https',):
        return HttpResponseBadRequest('Invalid scheme')
    if parsed.hostname != 'example.com':
        return HttpResponseBadRequest('Invalid host')
    resp = requests.get(url_str, timeout=5)
    resp.raise_for_status()
    return resp.content

Environment and client configuration

Ensure the Firestore client does not follow redirects to internal endpoints. Configure the client with explicit API endpoints only when using custom domains, and avoid accepting host parameters from users. Enforce least-privilege IAM service account permissions so that even if SSRF occurs, the blast radius is limited.

Defense-in-depth recommendations

  • Use Django form and model validation to enforce canonical formats.
  • Log rejected inputs for audit without exposing sensitive data.
  • Apply network-level egress controls to limit destinations (e.g., VPC Service Controls or firewall rules).
  • Periodically review IAM policies for the Firestore service account to ensure they follow least privilege.

Frequently Asked Questions

Can SSRF against a Django app lead to Firestore data leakage?
SSRF alone typically does not read Firestore data unless the compromised service account has overly broad permissions. However, SSRF can enable access to metadata services or internal endpoints, which may lead to privilege escalation or lateral movement. Mitigate by validating inputs and applying least-privilege IAM policies.
Does Firestore client configuration in Django need special handling to prevent SSRF?
The Firestore client does not follow HTTP redirects to internal services, but Django code that combines user input with Firestore operations or external HTTP calls can introduce risks. Use strict allowlists for document IDs and collection names, and avoid dynamic host configuration from user data.