HIGH path traversalecho gofirestore

Path Traversal in Echo Go with Firestore

Path Traversal in Echo Go with Firestore — how this specific combination creates or exposes the vulnerability

Path Traversal occurs when an API uses attacker-controlled input to build file or document paths without proper validation, allowing access to files or resources outside the intended directory or collection. In an Echo Go service that uses Firestore, this typically arises when a user-supplied identifier (such as a document ID or a path segment) is directly concatenated into Firestore document references or queries without normalization or strict allowlisting.

Consider an endpoint that retrieves user profile data by ID: GET /profiles/{userID}. If the handler passes userID directly into a Firestore document path, a request for /profiles/../../../secrets/config can result in a reference that resolves outside the intended profiles collection. While Firestore itself does not use a traditional filesystem path model, the equivalent risk is referencing documents or collections outside the expected scope. For example, a Firestore reference built from unchecked input could point to sensitive documents such as users/../../admin/settings if the input is not validated.

When combined with Firestore’s real-time listeners and flexible querying, an attacker may leverage traversal attempts to probe for accessible collections or documents, especially if security rules are misconfigured. Firestore rules that rely on request.resource.data without validating the document path can inadvertently permit reads or writes to unintended locations. Insecure rule logic such as allowing write access if request.resource.data.userId == request.auth.uid may still permit traversal within the user’s own subtree, but if the path is manipulated, the rule might not apply as intended.

In an automated scan using middleBrick, such endpoints would be flagged during the BOLA/IDOR and Input Validation checks. The scanner sends crafted inputs like ../../admin in place of path parameters and inspectulates Firestore access patterns and response behaviors. If the API returns data or does not enforce strict path scoping, middleBrick highlights the issue with severity and provides remediation guidance tied to the specific endpoint and Firestore interaction.

Additionally, Firestore’s use of structured paths means that traversal-like behavior can also manifest through array indices or map keys if input is not properly constrained. For example, an endpoint that dynamically builds a document path using user input without sanitization could expose nested collections such as organizations/{orgID}/users/{userID}/private, where orgID or userID originate from the request. middleBrick’s unauthenticated attack surface testing includes these scenarios to detect unintended data exposure before an attacker does.

Firestore-Specific Remediation in Echo Go — concrete code fixes

To mitigate Path Traversal in Echo Go with Firestore, validate and sanitize all user input used to construct document references or queries. Use allowlists for known-safe values and enforce strict schema checks before interacting with Firestore.

Secure Document Reference Construction

Instead of concatenating user input directly into a document path, parse and validate the input against expected patterns. For document IDs, use regular expressions to allow only alphanumeric characters and hyphens. Then, explicitly build the reference using the Firestore Go SDK.

import (
    "context"
    "regexp"
    "net/http"
    "github.com/labstack/echo/v4"
    "cloud.google.com/go/firestore"
)

func getProfile(c echo.Context) error {
    userID := c.Param("userID")
    matched, err := regexp.MatchString(`^[a-zA-Z0-9_-]{1,100}$`, userID)
    if err != nil || !matched {
        return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user identifier"})
    }

    ctx := c.Request().Context()
    client, err := firestore.NewClient(ctx, "your-project-id")
    if err != nil {
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to create client"})
    }
    defer client.Close()

    docRef := client.Collection("profiles").Doc(userID)
    var profile map[string]interface{}
    if err := docRef.Get(ctx, &profile); err != nil {
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to fetch profile"})
    }
    return c.JSON(http.StatusOK, profile)
}

Strict Query Scoping with Field Validation

When querying nested collections, ensure that parent document IDs are also validated and not derived from untrusted input. Use Firestore queries that explicitly scope to a known collection and document structure.

func getUserData(c echo.Context) error {
    orgID := c.Param("orgID")
    userID := c.Param("userID")

    if !isValidID(orgID) || !isValidID(userID) {
        return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid identifiers"})
    }

    ctx := c.Request().Context()
    client, err := firestore.NewClient(ctx, "your-project-id")
    if err != nil {
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": "client creation failed"})
    }
    defer client.Close()

    iter := client.Collection("organizations").Doc(orgID).Collection("users").Where(firestore.DocumentID, "==", userID).Documents(ctx)
    defer iter.Stop()

    if doc, err := iter.Next(); err == iterator.Done {
        return c.JSON(http.StatusNotFound, map[string]string{"error": "user not found"})
    } else if err != nil {
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": "query error"})
    } else {
        return c.JSON(http.StatusOK, doc.Data())
    }
}

func isValidID(id string) bool {
    matched, _ := regexp.MatchString(`^[a-zA-Z0-9_-]{1,50}$`, id)
    return matched
}

Firestore Security Rules Alignment

Complement Go-level validation with Firestore security rules that restrict reads and writes to expected paths. Rules should validate not only data content but also document path structure where possible.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /profiles/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    match /organizations/{orgId}/users/{userID} {
      allow read, write: if request.auth != null && request.auth.uid == userId && orgIdMatchesSomeCondition(orgId);
    }
  }
}

By combining strict input validation, explicit path construction, and aligned security rules, the risk of Path Traversal in an Echo Go and Firestore stack is significantly reduced. middleBrick can verify these controls by testing with crafted traversal inputs and inspecting whether the API enforces expected scoping.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can Firestore document IDs contain path traversal sequences like `..`?
Firestore document IDs can contain characters such as slashes in some configurations, but treating user input as part of a path without validation is unsafe. Always validate and sanitize IDs before using them in document references to avoid unintended access across collections or documents.
Does middleBrick test Firestore security rules for path traversal?
middleBrick focuses on unauthenticated attack surface testing and input validation behaviors. While it does not directly evaluate Firestore security rules, it detects whether crafted traversal-like inputs lead to unintended data exposure, which indicates potential rule or code weaknesses.