Llm Data Leakage in Gin with Firestore
Llm Data Leakage in Gin with Firestore — how this specific combination creates or exposes the vulnerability
When building a Go API with Gin that integrates Cloud Firestore, developers often serialize Firestore document snapshots directly into JSON responses. This practice can lead to LLM data leakage if the API is also used to interact with or evaluate Large Language Model (LLM) endpoints. middleBrick’s LLM/AI Security checks detect this by identifying unauthenticated LLM endpoints and scanning outputs for sensitive or inadvertently exposed data patterns, including PII, API keys, and executable code.
Firestore documents may contain fields such as email, api_key, or internal metadata that should never be returned to an LLM or logged in model responses. If an endpoint like /suggestions accepts user input, passes it to an LLM, and returns enriched Firestore data without strict output filtering, the response can leak credentials or personal information. For example, a Gin handler that merges Firestore data with LLM-generated content could expose an API key embedded in a document field through an LLM response, especially if the output is not scanned for sensitive content.
Additionally, Firestore security rules are enforced server-side and do not prevent application-layer leakage. A Gin service might read a document with elevated privileges and feed that data into an LLM prompt, unintentionally creating a prompt injection or data exfiltration path. middleBrick’s active prompt injection testing probes—including system prompt extraction, instruction override, DAN jailbreak, data exfiltration, and cost exploitation—can reveal whether Firestore-derived data is being improperly injected into LLM interactions. System prompt leakage detection further identifies whether Firestore metadata or structured data is exposed through insecure prompt construction or logging practices.
The combination of Gin, Firestore, and LLM integrations amplifies risk when handlers do not validate or sanitize Firestore outputs before LLM consumption. Without explicit output scanning for PII, API keys, and executable code, responses may contain sensitive fields that violate data minimization principles. middleBrick’s output scanning specifically targets these patterns in LLM responses, providing findings that map to OWASP API Top 10 and compliance frameworks such as GDPR and SOC2.
Firestore-Specific Remediation in Gin — concrete code fixes
To mitigate LLM data leakage in Gin applications using Firestore, apply strict field filtering and avoid passing raw document data to LLM prompts or responses. Use projection queries to retrieve only necessary fields, and sanitize outputs before any LLM interaction. The following examples demonstrate secure patterns.
First, define a minimal struct that includes only safe fields:
type SafeSuggestion struct {
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
}
Next, implement a Gin handler that reads from Firestore and maps to the safe struct:
import (
"context"
"github.com/gin-gonic/gin"
"cloud.google.com/go/firestore"
)
func GetSuggestion(c *gin.Context) {
ctx := context.Background()
client, err := firestore.NewClient(ctx, "your-project-id")
if err != nil {
c.JSON(500, gin.H{"error": "failed to create client"})
return
}
defer client.Close()
docRef := client.Collection("suggestions").Doc(c.Param("id"))
docSnap, err := docRef.Get(ctx)
if err != nil || !docSnap.Exists() {
c.JSON(404, gin.H{"error": "not found"})
return
}
var data map[string]interface{}
if err := docSnap.DataTo(&data); err != nil {
c.JSON(500, gin.H{"error": "failed to parse data"})
return
}
safe := SafeSuggestion{
ID: docSnap.Ref.ID,
Title: data["title"].(string),
Summary: data["summary"].(string),
}
c.JSON(200, safe)
}
When integrating with LLMs, ensure that Firestore data is never directly concatenated into prompts. Instead, pass only vetted values:
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
)
func LLMSuggestion(c *gin.Context) {
userInput := c.PostForm("query")
// Use only safe, filtered data
prompt := fmt.Sprintf("Suggest improvements for: %s", userInput)
// Call LLM with prompt, then return response without Firestore fields
c.JSON(200, gin.H{"response": "LLM response here"})
}
Finally, apply response-level filtering to remove any accidental leakage of keys or PII before returning data to the client or logging.
Related CWEs: llmSecurity
| CWE ID | Name | Severity |
|---|---|---|
| CWE-754 | Improper Check for Unusual or Exceptional Conditions | MEDIUM |