Nosql Injection in Chi with Firestore
Nosql Injection in Chi with Firestore — how this specific combination creates or exposes the vulnerability
Chi is a minimal, idiomatic router for Go that encourages explicit parameter handling and structured routing. When Chi endpoints interact with Google Cloud Firestore, improper handling of user input can lead to NoSQL injection. Firestore queries often build filters programmatically; if keys, field names, or values are derived directly from untrusted data without strict validation, an attacker can manipulate query semantics.
Consider a route like /users/{userID} where userID is used to construct a Firestore document lookup. If the application does not sanitize or strictly type-check the parameter, an attacker can supply a payload such as {"$ne": null} to affect query logic. In Firestore, field-based injection can occur when input is used in map keys or field paths, potentially bypassing intended access controls or data isolation.
Chi does not impose a model-binding layer by default; developers must explicitly decode and validate inputs. Without this, parameters intended for path segments can leak into query or document field construction. For example, a handler that builds a Firestore query using raw JSON from the request body may inadvertently allow injection if the JSON keys are forwarded to Firestore field selectors. This can lead to over-permissive reads, enumeration of collections, or unauthorized document access.
Real-world patterns that increase risk include concatenating user input into Firestore collection or document IDs, or using dynamic keys in map[string]interface{} structures that are later passed to Where or Select. Since Firestore does not support parameterized queries in the same way relational databases do, each query construction step must be validated. Attack patterns such as field manipulation or injection into array operators are feasible when input is not rigorously constrained.
middleBrick detects these risks by analyzing the unauthenticated attack surface of your Chi service, including OpenAPI specs if provided, and by correlating runtime behavior with Firestore-specific query patterns. It flags insecure usage of document references, dynamic field selectors, and missing input sanitization that could enable NoSQL injection in the context of Chi and Firestore.
Firestore-Specific Remediation in Chi — concrete code fixes
Remediation centers on strict input validation, avoiding dynamic field names, and using Firestore’s type-safe query helpers. Always treat user input as untrusted and never directly embed it into field paths or document references.
1. Validate and constrain Chi route parameters
Use Chi’s middleware to validate and sanitize parameters before they reach business logic. Enforce type and format constraints explicitly.
import (
"net/http"
"regexp"
"github.com/go-chi/chi/v5"
)
var userIDRE = regexp.MustCompile(`^[A-Za-z0-9_-]{1,64}$`)
func UserMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "userID")
if !userIDRE.MatchString(userID) {
http.Error(w, "invalid user identifier", http.StatusBadRequest)
return
}
next.ServeHTTP(w, r)
})
}
2. Use Firestore document references safely
Build document references using constant collection names and validated IDs only. Avoid string concatenation with raw input.
import (
"context"
"firebase.google.com/go/v4"
"google.golang.org/api/iterator"
)
func GetUser(ctx context.Context, client *firestore.Client, userID string) (*firestore.DocumentSnapshot, error) {
// Safe: collection name is constant, userID is validated upstream
docRef := client.Collection("users").Doc(userID)
return docRef.Get(ctx)
}
3. Avoid dynamic field names in Firestore queries
Do not use user-controlled values as field paths in Where clauses. Use a strict allowlist if field selection is necessary.
import "cloud.google.com/go/firestore"
var allowedFields = map[string]bool{
"email": true,
"status": true,
}
func QueryUsers(ctx context.Context, client *firestore.Client, field, value string) (*firestore.QuerySnapshot, error) {
if !allowedFields[field] {
return nil, http.ErrAbortHandler
}
q := client.Collection("users").Where(field, "==", value)
return q.Get(ctx)
}
4. Sanitize JSON keys before using them in query construction
If you accept JSON for filtering, unmarshal into a struct or a validated map, and do not forward raw keys to Firestore field selectors.
import "encoding/json"
type FilterInput struct {
Email string `json:"email"`
Status string `json:"status"`
}
func ParseFilter(body []byte) (FilterInput, error) {
var f FilterInput
if err := json.Unmarshal(body, &f); err != nil {
return FilterInput{}, err
}
// Further validation on f.Email and f.Status can be applied here
return f, nil
}
5. Apply principle of least privilege to Firestore IAM
Ensure the service account used by your Chi service has read/write permissions limited to the required collections and operations. This reduces the impact of any potential injection.