HIGH pii leakagegorilla mux

Pii Leakage in Gorilla Mux

How PII Leakage Manifests in Gorilla Mux

PII leakage in Gorilla Mux applications typically occurs through improper handling of request data, inadequate validation of path parameters, and failure to sanitize query parameters. The router's flexible parameter extraction can inadvertently expose sensitive information if developers aren't careful about what data they log, return in error responses, or include in API responses.

One common pattern is using {param} in route definitions without proper validation. Consider this vulnerable endpoint:

r := mux.NewRouter()
r.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]
    
    // Direct database query without validation
    user, err := db.GetUserByID(id)
    if err != nil {
        http.Error(w, err.Error(), 500) // Leaks database error with PII
        return
    }
    
    json.NewEncoder(w).Encode(user) // May expose sensitive fields
})("/users/{id}")

This code has multiple PII leakage vectors: database errors might contain table names or query details, and the user struct could include fields like social security numbers, addresses, or financial data that shouldn't be exposed to unauthenticated users.

Another Gorilla Mux-specific issue arises with path parameter extraction. The router doesn't enforce type constraints by default:

r.HandleFunc("/accounts/{accountID}", func(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    accountID := vars["accountID"]
    
    // No validation that accountID is numeric
    acc, err := db.GetAccount(accountID)
    if err != nil {
        http.Error(w, "Account not found", 404) // Generic error, but still problematic
    }
    
    json.NewEncoder(w).Encode(acc) // Full account object exposed
})("/accounts/{accountID}")

An attacker could exploit this by requesting /accounts/1 OR 1=1 or similar injection attempts, potentially triggering database errors that leak schema information or causing the application to return data for accounts they shouldn't access.

Query parameter handling in Gorilla Mux also presents risks. The router's Request.URL.Query() returns all parameters without validation:

r.HandleFunc("/search", func(w http.ResponseWriter, r *http.Request) {
    query := r.URL.Query().Get("q")
    
    // No sanitization of query parameter
    results, err := db.SearchUsers(query)
    if err != nil {
        http.Error(w, err.Error(), 500) // Database error leakage
        return
    }
    
    json.NewEncoder(w).Encode(results) // May include sensitive user data
})("/search")

Without proper sanitization, this endpoint could return entire user profiles based on partial information, exposing PII to anyone who can guess or brute-force valid search terms.

Gorilla Mux-Specific Detection

Detecting PII leakage in Gorilla Mux applications requires examining both the routing configuration and the handler implementations. The first step is to audit your route definitions for overly permissive patterns.

Start by scanning your router configuration:

package main

import (
    "fmt"
    "net/http"
    "github.com/gorilla/mux"
)

func auditRoutes(router *mux.Router) {
    // Walk through all registered routes
    router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
        pathTemplate, err := route.GetPathTemplate()
        if err != nil {
            return err
        }
        
        fmt.Printf("Route: %s\n", pathTemplate)
        
        // Check for problematic patterns
        if strings.Contains(pathTemplate, "{id}") || 
           strings.Contains(pathTemplate, "{user}") ||
           strings.Contains(pathTemplate, "{email}") {
            fmt.Printf("  WARNING: Route contains potentially sensitive parameter: %s\n", pathTemplate)
        }
        
        return nil
    })
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/users/{id}", userHandler)
    r.HandleFunc("/accounts/{accountID}", accountHandler)
    
    auditRoutes(r)
}

This audit helps identify routes that might be handling sensitive data. However, static analysis only catches obvious issues. For comprehensive detection, you need runtime scanning that tests actual API behavior.

This is where middleBrick provides unique value for Gorilla Mux applications. As a black-box scanner, it tests your running API endpoints without requiring source code access or credentials. middleBrick's PII leakage detection includes:

  • Pattern matching for common PII formats (SSNs, credit card numbers, addresses, phone numbers)
  • Testing for information disclosure in error responses
  • Checking for excessive data exposure in successful responses
  • Verifying authentication requirements for sensitive endpoints
  • Testing for BOLA (Broken Object Level Authorization) vulnerabilities that could expose PII

To use middleBrick with your Gorilla Mux API:

# Install the CLI tool
npm install -g middlebrick

# Scan your API endpoint
middlebrick scan https://api.yourservice.com/users/123

# For CI/CD integration
middlebrick scan --threshold B --format json https://api.yourservice.com/ > report.json

The scanner runs 12 security checks in parallel, including specific PII detection patterns that would catch issues like returning full user profiles, leaking database errors with schema information, or exposing sensitive fields in API responses.

Gorilla Mux-Specific Remediation

Remediating PII leakage in Gorilla Mux applications requires a defense-in-depth approach. Start with input validation and sanitization using Gorilla Mux's built-in features.

For path parameter validation, use regular expression constraints in your route definitions:

r := mux.NewRouter()

// Only allow numeric IDs
r.HandleFunc("/users/{id:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]
    
    // Now we know id is numeric - safe to use in database queries
    user, err := db.GetUserByID(id)
    if err != nil {
        http.Error(w, "User not found", 404) // Generic error, no PII leakage
        return
    }
    
    // Create a sanitized response struct
    response := struct {
        ID        string `json:"id"`
        Name      string `json:"name"`
        Email     string `json:"email,omitempty"`
    }{
        ID:   user.ID,
        Name: user.Name,
    }
    
    json.NewEncoder(w).Encode(response) // Only expose necessary fields
})("/users/{id:[0-9]+}")

This approach prevents injection attacks through path parameters and ensures you only process valid input. The regex constraint [0-9]+ guarantees the ID is numeric before your handler code executes.

For query parameters, implement explicit validation and sanitization:

r.HandleFunc("/search", func(w http.ResponseWriter, r *http.Request) {
    query := r.URL.Query().Get("q")
    
    // Validate and sanitize input
    if query == "" || len(query) > 100 {
        http.Error(w, "Invalid search query", 400)
        return
    }
    
    // Sanitize to prevent injection
    sanitizedQuery := sanitizeInput(query)
    
    // Use parameterized queries to prevent SQL injection
    results, err := db.SearchUsersWithLimit(sanitizedQuery, 10)
    if err != nil {
        http.Error(w, "Search failed", 500) // Generic error
        return
    }
    
    // Create sanitized response
    var sanitizedResults []struct {
        ID    string `json:"id"`
        Name  string `json:"name"`
    }
    
    for _, user := range results {
        sanitizedResults = append(sanitizedResults, struct {
            ID   string `json:"id"`
            Name string `json:"name"`
        }{
            ID:   user.ID,
            Name: user.Name,
        })
    }
    
    json.NewEncoder(w).Encode(sanitizedResults)
})("/search")

The key improvements here are input validation (length check), sanitization function, parameterized database queries, and creating a response struct that only includes necessary fields.

For comprehensive PII protection, implement middleware that automatically sanitizes responses:

type piiSanitizer struct {
    next http.Handler
}

func (ps *piiSanitizer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // Create a buffer to capture the response
    rec := httptest.NewRecorder()
    ps.next.ServeHTTP(rec, r)
    
    // Read the response body
    body := rec.Body.Bytes()
    
    // Check if it's JSON
    var data map[string]interface{}
    if json.Unmarshal(body, &data) == nil {
        // Sanitize the data structure
        sanitized := sanitizePII(data)
        
        // Write the sanitized response
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(sanitized)
    } else {
        // Non-JSON response, write as-is
        w.WriteHeader(rec.Code)
        w.Write(body)
    }
}

func sanitizePII(data map[string]interface{}) map[string]interface{} {
    sanitized := make(map[string]interface{})
    
    for key, value := range data {
        switch key {
        case "ssn", "social_security_number", "credit_card", "cvv":
            // Remove or mask sensitive fields
            sanitized[key] = "[REDACTED]"
        case "email", "phone":
            // Allow some fields but consider if they should be exposed
            sanitized[key] = value
        default:
            sanitized[key] = value
        }
    }
    
    return sanitized
}

// Use the middleware
r.Use(func(next http.Handler) http.Handler {
    return &piiSanitizer{next: next}
})

This middleware automatically scans all JSON responses and removes or masks sensitive fields before they're sent to the client.

For production deployment, integrate middleBrick into your CI/CD pipeline to catch PII leakage before deployment:

# .github/workflows/security.yml
name: Security Scan

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run middleBrick Scan
        run: |
          npm install -g middlebrick
          middlebrick scan --threshold B --format json https://staging.yourservice.com/ > middlebrick-report.json
      - name: Fail on high risk
        run: |
          SCORE=$(jq '.score' middlebrick-report.json)
          if [ $SCORE -lt 80 ]; then
            echo "Security score below threshold: $SCORE"
            exit 1
          fi

This ensures that any PII leakage vulnerabilities are caught automatically during development, preventing them from reaching production.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

How does Gorilla Mux's path parameter handling differ from other Go routers regarding PII leakage?
Gorilla Mux provides powerful path parameter extraction with mux.Vars(r), but unlike some routers that enforce strict typing, it returns all parameters as strings without validation. This means you must explicitly validate and sanitize parameters in your handlers. The router also doesn't provide built-in PII detection or automatic field filtering, so developers must implement their own security measures to prevent sensitive data exposure.
Can middleBrick scan my Gorilla Mux API if it's behind authentication?
middleBrick performs black-box scanning without requiring credentials, so it tests your API's unauthenticated attack surface. This is actually beneficial for PII leakage detection because it reveals what information is exposed to unauthenticated users. For comprehensive testing, you should run middleBrick against both public and authenticated endpoints (using the CLI or CI/CD integration where you can provide test credentials separately).