HIGH cache poisoninggorilla muxbasic auth

Cache Poisoning in Gorilla Mux with Basic Auth

Cache Poisoning in Gorilla Mux with Basic Auth — how this specific combination creates or exposes the vulnerability

Cache poisoning occurs when an attacker causes a shared cache to store malicious content, leading other users to receive harmful responses. When using Gorilla Mux with HTTP Basic Authentication, the risk arises because the cache key may not sufficiently differentiate between authenticated and unauthenticated contexts or between different users. If a cached response is generated from a request that includes Basic Auth credentials and that response is later served to a different user without credentials, sensitive information can be leaked or an authenticated session can be hijacked.

Gorilla Mux is a powerful URL router and dispatcher, but it does not inherently manage cache behavior. Developers often integrate it with reverse proxies or in-memory caches. The combination of Basic Auth and caching becomes dangerous when the Authorization header is either omitted from the cache key or improperly handled. For example, if a request with Authorization: Basic dXNlcjpwYXNz is cached and then served to another user who did not provide credentials, the cached response may expose data that should be restricted. Similarly, if user-specific data is included in a response that is cached based only on the request path, an attacker who can cause a victim’s browser to make an authenticated request might poison the cache with content tailored to the victim.

Real-world attack patterns involve inducing authenticated users to request a resource that includes sensitive data, which is then cached and subsequently retrieved by unauthenticated users. This can violate confidentiality and lead to information disclosure. In the context of OWASP API Top 10, this maps closely to Broken Object Level Authorization (BOLA) and Cache Poisoning categories. MiddleBrick scans detect such misconfigurations by analyzing OpenAPI specifications and runtime behavior, identifying cases where Authorization headers are not considered in cache partitioning or where responses containing sensitive data lack proper cache-control directives.

Common misconfigurations include failing to set Vary: Authorization on responses that vary by credentials and caching authenticated responses in shared storage. Without this header, intermediaries may incorrectly treat responses as interchangeable. Additionally, if cache keys are constructed solely from the request URI and query parameters, they neglect the Authorization header, enabling cross-user contamination. MiddleBrick’s checks for Data Exposure and Authentication validate these aspects, ensuring that cached responses respect user boundaries and that proper cache-control headers are present.

Basic Auth-Specific Remediation in Gorilla Mux — concrete code fixes

To mitigate cache poisoning when using Basic Auth with Gorilla Mux, ensure that authenticated responses are not cached in shared storage and that cache keys incorporate the Authorization header. Use explicit cache-control headers and the Vary header to instruct caches on how to differentiate responses.

Example: Secure handler with cache-control and vary headers

package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
)

func authenticatedHandler(w http.ResponseWriter, r *http.Request) {
	// Validate Basic Auth credentials
	username, password, ok := r.BasicAuth()
	if !ok || !isValidUser(username, password) {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Set cache-control to prevent shared caching of authenticated responses
	w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, private")
	// Vary on Authorization to ensure caches store separate versions per user
	w.Header().Set("Vary", "Authorization")

	// Safe, user-specific response
	fmt.Fprintf(w, "Hello, %s", username)
}

func isValidUser(username, password string) bool {
	// Implement secure credential validation
	return username == "alice" && password == "secret"
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/user/profile", authenticatedHandler).Methods("GET")
	http.ListenAndServe(":8080", r)
}

Example: Middleware to enforce no-cache for authenticated routes

func noCacheMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// If request includes Basic Auth, prevent caching
		if _, _, ok := r.BasicAuth(); ok {
			w.Header().Set("Cache-Control", "no-store")
			w.Header().Set("Vary", "Authorization")
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	r := mux.NewRouter()
	// Apply middleware globally or to specific routes
	r.Use(noCacheMiddleware)
	r.HandleFunc("/public", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Cache-Control", "public, max-age=3600")
		w.Write([]byte("public data"))
	}).Methods("GET")
	http.ListenAndServe(":8080", r)
}

Operational guidance

  • Always set Cache-Control: no-store or private for responses containing user-specific data after Basic Auth validation.
  • Include Vary: Authorization on any response that changes based on credentials to prevent shared caches from serving one user’s response to another.
  • Avoid caching authenticated responses in shared caches; prefer private caches or non-cached flows for sensitive endpoints.
  • Audit OpenAPI specs and runtime behavior using tools like MiddleBrick to detect missing cache headers or improper authentication handling.

Frequently Asked Questions

How can I verify that my Gorilla Mux endpoints are not vulnerable to cache poisoning with Basic Auth?
Use MiddleBrick to scan your API endpoints. It checks for missing Vary headers, improper Cache-Control directives, and whether Authorization is considered in cache differentiation. Review the report for findings related to Data Exposure and Authentication.
Does using Basic Auth over HTTPS fully protect against cache poisoning?
Using Basic Auth over HTTPS protects credentials in transit, but it does not prevent caching issues. If responses lack proper Cache-Control and Vary headers, caches may still store and serve sensitive data to unauthorized users, regardless of transport security.