GuardAPI

Fix BOLA (Broken Object Level Authorization) in Gorilla

BOLA (formerly IDOR) remains the #1 threat in the OWASP API Top 10. In Gorilla mux, the vulnerability manifests when a developer extracts a resource ID from `mux.Vars(r)` and queries the database without verifying if the authenticated user has permission to access that specific object. If you're fetching data based solely on a URL parameter, you're leaking data.

The Vulnerable Pattern

func GetOrder(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	orderID := vars["id"]
var order Order
// VULNERABLE: Direct object reference without ownership verification
err := db.QueryRow("SELECT id, total, status FROM orders WHERE id = ?", orderID).Scan(&order.ID, &order.Total, &order.Status)
if err != nil {
	http.Error(w, "Not Found", http.StatusNotFound)
	return
}

json.NewEncoder(w).Encode(order)

}

The Secure Implementation

To kill BOLA, you must implement fine-grained access control. First, ensure your authentication middleware injects the user's identity into the request context. Second, never trust the `{id}` from the Gorilla router as the sole key for a lookup. Always include the authenticated `userID` in your SQL `WHERE` clause or perform a manual ownership check before returning the object. This ensures that even if an attacker guesses a valid UUID/ID, the database will return zero rows because the ownership doesn't match the session.

func GetOrder(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	orderID := vars["id"]
// Retrieve authenticated UserID from context (populated by Auth Middleware)
userID, ok := r.Context().Value("userID").(string)
if !ok {
	http.Error(w, "Unauthorized", http.StatusUnauthorized)
	return
}

var order Order
// SECURE: Query includes the owner_id to enforce authorization at the database level
query := "SELECT id, total, status FROM orders WHERE id = ? AND user_id = ?"
err := db.QueryRow(query, orderID, userID).Scan(&order.ID, &order.Total, &order.Status)

if err == sql.ErrNoRows {
	// Return 403 or 404 to prevent ID enumeration
	http.Error(w, "Access Denied", http.StatusForbidden)
	return
}

json.NewEncoder(w).Encode(order)

}

About this page

Framework notes in /guides are generated sketches kept for URL stability. They are not human pentest reports and they are not GuardAPI scan output. The product is a GET-only BOLA merge gate. Maintained by GuardAPI. Questions: support@guard-api.com