Overview
Broken Object Level Authorization (BOLA) is when an API returns or changes a resource based on an ID without verifying entitlement. Attackers can access other users' data, modify resources, or perform restricted actions, leading to data exposure and trust damage.
In Echo-based Go apps, BOLA often shows up in endpoints that take an object ID in the path (for example, /resources/:id) and fetch the resource without checking ownership.
This vulnerability manifests across CRUD endpoints and can be worsened by token claims not being validated against resource ownership. The fix is to enforce per-resource authorization either in handlers or via middleware.
Remediation strategies include deny-by-default, attaching user identity to the request via middleware, validating ownership (resource.OwnerID == user.ID), and adopting RBAC/ABAC with tests for unauthorized access.
Code Fix Example
Echo API Security Remediation
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
type Resource struct {
ID string
OwnerID string
Data string
}
var resources = map[string]Resource{
"1": {ID: "1", OwnerID: "alice", Data: "Alice's secret"},
"2": {ID: "2", OwnerID: "bob", Data: "Bob's secret"},
}
func vulnerableGetResource(c echo.Context) error {
id := c.Param("id")
res, ok := resources[id]
if !ok {
return c.NoContent(http.StatusNotFound)
}
// Vulnerable: no authorization check, returns resource regardless of owner
return c.JSON(http.StatusOK, res)
}
func fixedGetResource(c echo.Context) error {
userID := c.Request().Header.Get("X-User")
if userID == "" {
return c.NoContent(http.StatusUnauthorized)
}
id := c.Param("id")
res, ok := resources[id]
if !ok {
return c.NoContent(http.StatusNotFound)
}
if res.OwnerID != userID {
return c.NoContent(http.StatusForbidden)
}
return c.JSON(http.StatusOK, res)
}
func main() {
e := echo.New()
e.GET("/resources/:id", vulnerableGetResource)
e.GET("/secure/resources/:id", fixedGetResource)
// Start server (will listen on :8080 by default)
e.Start(":8080")
}