HIGH ssrf server sideginfirestore

Ssrf Server Side in Gin with Firestore

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

Server-side request forgery (SSRF) in a Gin application that interacts with Google Firestore can arise when user-supplied input is used to form HTTP requests or to construct Firestore resource references without strict validation. In this stack, an attacker may supply a malicious URL or document path that causes the server to make unintended internal requests or to access Firestore resources it should not reach. For example, if an endpoint accepts a Firestore document path from a query parameter and passes it directly to the Firestore client, an attacker can reference internal metadata services or other projects by supplying paths such as http://metadata or manipulated Firestore paths that bypass intended access controls.

Gin does not automatically validate or sanitize inputs used to build Firestore client calls, so developers must enforce strict allowlists for document IDs and collection names. A vulnerable pattern is concatenating user input into a Firestore path and then using the Firestore Go SDK to retrieve data, which may cause the server to follow injected redirections or SSRF-inducing HTTP calls when the Firestore client or underlying HTTP transport is misconfigured. In a black-box scan, middleBrick tests such endpoints by submitting crafted document paths and metadata-service targets to detect whether the server performs unauthorized internal requests or exposes sensitive data through misrouted Firestore lookups.

Because Firestore rules are enforced client-side in some implementations, server-side code must also enforce its own authorization checks. If the Gin handler trusts user input to determine which Firestore document to read or write, and does not validate that the authenticated subject has permission on that specific document, the SSRF vector can combine with broken access control to yield unauthorized data exposure. middleBrick’s checks include submitting path traversal and internal network indicators to see whether the server performs outbound requests to sensitive endpoints, and whether Firestore operations reflect user-controlled input without proper validation.

Firestore-Specific Remediation in Gin — concrete code fixes

Remediation centers on strict input validation, avoiding direct concatenation of user input into Firestore document paths, and using Firestore’s built-in APIs safely. Always treat document IDs and collection names as untrusted, and validate them against an allowlist or a strict regex before using them with the Firestore client.

Example: Safe Firestore document read in Gin

package main

import (
	"context"
	"fmt"
	"net/http"
	"regexp"

	"github.com/gin-gonic/gin"
	"cloud.google.com/go/firestore"
	"google.golang.org/api/iterator"
)

var validID = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,100}$`)

func getDocument(c *gin.Context) {
	// Assume Firestore client is initialized elsewhere and passed in
	client, _ := firestore.NewClient(context.Background(), "my-project-id")
	defer client.Close()

	collection := c.Param("collection")
	docID := c.Param("docID")

	// Validate collection and document ID
	if !validID.MatchString(collection) || !validID.MatchString(docID) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid collection or document ID"})
		return
	}

	ctx := context.Background()
	iter := client.Collection(collection).Doc(docID).Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to read document"})
			return
		}
		if doc.Ref == nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "document not found"})
			return
		}
		data := doc.Data()
		c.JSON(http.StatusOK, gin.H{"data": data})
		break
	}
}

Key points in the example:

  • Use a strict regex to validate collection and document inputs instead of relying on Firestore security rules alone.
  • Use the Firestore Go SDK’s Collection and Doc methods with validated identifiers rather than building paths from raw strings.
  • Do not follow user-supplied URLs or redirects; if you must fetch external resources, use a tightly scoped HTTP client with a deny-list of private IP ranges and metadata service targets.

Example: Parameterized Firestore query with allowlisted fields

func queryWithAllowlist(c *gin.Context) {
	client, _ := firestore.NewClient(context.Background(), "my-project-id")
	defer client.Close()

	// Accept only specific, known fields from query params
	field := c.Query("field")
	value := c.Query("value")

	allowedFields := map[string]bool{"status": true, "region": true, "tags": true}
	if !allowedFields[field] {
		c.JSON(http.StatusBadRequest, gin.H{"error": "field not allowed"})
		return
	}

	iter := client.Collection("items").Where(field, "==", value).Documents(context.Background())
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "query failed"})
			return
		}
		c.JSON(http.StatusOK, gin.H{"id": doc.Ref.ID, "data": doc.Data()})
	}
}

Additional measures include configuring the HTTP transport used by the Firestore client to block connections to private IP ranges and metadata endpoints, and enforcing least-privilege IAM roles for the service account used by the Gin application. middleBrick’s scans validate that such controls are observable in runtime behavior by checking for SSRF indicators and improper access patterns across the 12 security checks.

Frequently Asked Questions

How can I prevent SSRF when accepting Firestore document paths from users in Gin?
Validate collection and document IDs with a strict allowlist regex, avoid concatenating user input into paths, use the Firestore Go SDK’s Collection and Doc methods with validated identifiers, and ensure your HTTP transport blocks private IP and metadata targets.
Does Firestore’s server-side security rules alone protect against SSRF in Gin?
Firestore rules are enforced in the context of authenticated client requests; server-side Gin code must also validate inputs because SSRF involves the server making unauthorized outbound requests or reading unintended resources independent of Firestore rules.