HIGH open redirectfirestore

Open Redirect in Firestore

How Open Redirect Manifests in Firestore

Open Redirect vulnerabilities in Firestore applications typically arise from improper handling of user-supplied URLs in redirect logic. In Firestore contexts, this often occurs when applications use client-side routing or authentication flows that dynamically construct redirect URLs based on query parameters or database-stored values.

A common Firestore pattern involves storing redirect URLs in documents and using them for post-authentication navigation. Consider this vulnerable implementation:

const userDoc = await db.collection('users').doc(userId).get();
const redirectUrl = userDoc.data().redirectUrl;
res.redirect(redirectUrl);

The vulnerability here is that redirectUrl comes directly from Firestore without validation. An attacker could modify their user document to store https://evil.com or a phishing URL, causing all users who authenticate to be redirected to malicious sites.

Another Firestore-specific pattern involves using collection names as redirect targets:

const collection = req.query.collection || 'default';
const doc = await db.collection(collection).doc('landing').get();
res.redirect(doc.data().url);

This is vulnerable because an attacker can supply any collection name via the query parameter, potentially accessing documents they shouldn't see and extracting redirect URLs from arbitrary collections.

Firestore's security rules can also introduce redirect vulnerabilities when improperly configured. Consider rules that allow read access based on dynamic parameters:

match /redirects/{redirectId} {
  allow read: if request.auth != null;
}

Combined with client-side URL construction, this allows authenticated users to read any redirect document and potentially chain it with other vulnerabilities.

Mobile applications using Firestore often implement deep linking with redirects. A vulnerable pattern looks like:

const deepLink = await db.collection('deeplinks').doc(id).get();
window.location.href = deepLink.data().targetUrl;

If targetUrl isn't validated against an allowlist, attackers can create malicious deep links that redirect users to phishing sites or execute script-based attacks through URL schemes.

Firestore-Specific Detection

Detecting Open Redirect vulnerabilities in Firestore applications requires examining both the database structure and application code. Start by auditing your Firestore collections for URL fields that might be used in redirects.

Collections to examine:

  • redirects - often contains URL fields like targetUrl, destination, next
  • users - may contain postLoginRedirect, callbackUrl, returnTo
  • settings - might store defaultRedirect, fallbackUrl
  • marketing - could contain campaignUrl, trackingLink

Use the Firestore CLI to export suspicious collections:

firebase firestore:export --collections=redirects,users/settings
# Then search exported JSON for URL patterns
jq '.[] | select(.targetUrl? != null)' redirects.json

Static analysis of your application code should look for patterns where Firestore data flows into redirect functions:

grep -r 'res\.redirect\|window\.location\.href' --include='*.js' --include='*.ts'
grep -A5 -B5 'redirect\|location' --include='*.js' --include='*.ts'

middleBrick's Firestore-specific scanning identifies Open Redirect vulnerabilities by:

  1. Analyzing your OpenAPI spec to understand redirect endpoints
  2. Testing unauthenticated access to redirect collections
  3. Attempting parameter injection in redirect URLs
  4. Checking if redirect targets are validated against allowlists

The scanner tests common attack vectors like:

// Test for unvalidated redirects
GET /api/redirect?to=https://evil.com
// Test for Firestore document injection
GET /api/redirect?docId=malicious-document

middleBrick reports findings with severity levels based on the impact. A critical finding indicates that unauthenticated users can redirect to arbitrary domains, while a high finding suggests authenticated users can manipulate redirect targets to external domains.

Firestore-Specific Remediation

Remediating Open Redirect vulnerabilities in Firestore applications requires a defense-in-depth approach. The most effective strategy combines input validation, allowlisting, and secure defaults.

Implement URL validation using a strict allowlist approach:

const allowedDomains = [
  'https://yourapp.com',
  'https://app.yourapp.com',
  'https://docs.yourapp.com'
];

function validateRedirectUrl(url) {
  try {
    const parsed = new URL(url);
    return allowedDomains.some(domain => 
      parsed.hostname === new URL(domain).hostname
    );
  } catch (e) {
    return false;
  }
}

// Secure implementation
const redirectUrl = userDoc.data().redirectUrl;
if (validateRedirectUrl(redirectUrl)) {
  res.redirect(redirectUrl);
} else {
  res.redirect('/default-dashboard');
}

For Firestore security rules, implement read restrictions that prevent unauthorized URL access:

match /redirects/{redirectId} {
  allow read: if 
    request.auth != null &&
    (request.auth.token.email_verified == true ||
     request.auth.token.phone_number_verified == true);
}

match /users/{userId} {
  allow read: if request.auth.uid == userId;
  allow update: if request.auth.uid == userId &&
                validateRedirectUrl(resource.data.redirectUrl);
}

Store only relative paths in Firestore and construct full URLs server-side:

// In Firestore: store '/dashboard' instead of full URL
const userDoc = await db.collection('users').doc(userId).get();
const path = userDoc.data().redirectPath || '/dashboard';
const fullUrl = new URL(path, process.env.BASE_URL).href;
res.redirect(fullUrl);

Implement a redirect service with centralized validation:

class RedirectService {
  constructor() {
    this.allowedDomains = new Set([
      'yourapp.com',
      'app.yourapp.com'
    ]);
    this.defaultRedirect = '/dashboard';
  }

  async getRedirect(userId, requestedPath) {
    const userDoc = await db.collection('users').doc(userId).get();
    const storedPath = userDoc.data().redirectPath;
    
    const path = requestedPath || storedPath || this.defaultRedirect;
    const fullUrl = new URL(path, process.env.BASE_URL).href;
    
    if (!this.validateUrl(fullUrl)) {
      return new URL(this.defaultRedirect, process.env.BASE_URL).href;
    }
    
    return fullUrl;
  }

  validateUrl(url) {
    try {
      const parsed = new URL(url);
      return this.allowedDomains.has(parsed.hostname);
    } catch {
      return false;
    }
  }
}

Add monitoring to detect suspicious redirect patterns:

functions.firestore
  .document('redirects/{redirectId}')
  .onWrite((change, context) => {
    const newData = change.after.data();
    if (newData && newData.targetUrl) {
      admin.analytics().logEvent('redirect_created', {
        url: newData.targetUrl,
        userId: context.auth?.uid
      });
    }
  });

Frequently Asked Questions

How does middleBrick detect Open Redirect vulnerabilities in Firestore applications?
middleBrick scans your API endpoints by testing unvalidated redirect parameters and attempting to inject malicious URLs. It analyzes your OpenAPI spec to identify redirect endpoints, then systematically tests parameter injection, URL validation bypass attempts, and checks if redirect targets are properly validated against allowlists. The scanner reports findings with severity levels and provides specific remediation guidance for Firestore contexts.
Can Firestore security rules prevent Open Redirect attacks?
Firestore security rules can help but aren't sufficient alone. Rules can restrict who can read redirect documents and validate URL formats, but they can't validate that URLs point to allowed domains or prevent client-side manipulation. You need both secure rules AND application-level validation. For example, rules can ensure only authenticated users read redirects, but your application code must still validate that redirect URLs point to approved domains before performing the redirect.