Broken Object Level Authorization

Broken Object Level Authorization in Go (Gin) [Apr 2026] [CVE-2026-35604]

[Fixed Apr 2026] Updated CVE-2026-35604

Overview

Broken Object Level Authorization (BOLA) vulnerabilities arise when an API fails to verify a caller's right to access a specific object, instead trusting object identifiers or tokens alone. In real-world systems, this can enable access to files, records, or resources after permissions have been revoked, simply because a previously valid link or token still exists. This class of flaw is especially dangerous in file-sharing interfaces where public links grant access to sensitive assets. If permission revocation is not enforced at request time, attackers may access, download, or preview resources they should no longer be permitted to see. CVE-2026-35604 exemplifies this risk in the File Browser project: before version 2.63.1, when an admin revokes a user's Share and Download permissions, existing share links created by that user remain fully accessible to unauthenticated users because the public share download handler does not re-check the share owner's current permissions. This specific vulnerability is categorized under CWE-863 and was fixed in 2.63.1. In Go (Gin) applications, similar patterns can occur if handlers rely on a public link or token without re-validating the owner's active permissions on each access, leading to stale or revoked permissions being honored by the system. In a Go (Gin) context, a vulnerable pattern often looks up a resource via a share identifier and serves the file without reloading and validating the owner’s current rights. Attackers can still access the resource if the share exists even after permissions are revoked, because the authorization check happened only at share creation time. The remediation is to perform a fresh authorization check during each access, ensuring the share is active and the owner still has the necessary rights, before serving any resource. Remediation involves centralizing the access gate for object-level resources and performing real-time checks against both the share state and the owner's permissions. Do not rely on the presence of a public link or a stored token as proof of ongoing authorization. Implement explicit, server-side permission checks in Go (Gin), and validate the owner’s rights each time a resource is requested, with proper error handling and auditing.

Affected Versions

File Browser < 2.63.1 (i.e., 2.63.0 and earlier)

Code Fix Example

Go (Gin) API Security Remediation
// Vulnerable and fixed patterns in one file (Go with Gin)
package main

import (
    "net/http"
    log "log"

    gin "github.com/gin-gonic/gin"
)

type Share struct {
    ID       string
    FilePath string
    OwnerID  string
    Active   bool
}

type Owner struct {
    ID          string
    CanDownload bool
    Active      bool
}

var shares = map[string]Share{
    "s1": {ID: "s1", FilePath: `demo/files/report.pdf`, OwnerID: "u1", Active: true},
}

var owners = map[string]Owner{
    "u1": {ID: "u1", CanDownload: true, Active: true},
}

func main() {
    r := gin.Default()

    // Vulnerable route: does not re-check owner's permissions on access
    r.GET("/share/download/:shareID", downloadVulnerable)

    // Fixed route: re-validates permissions at access time
    r.GET("/secure/share/download/:shareID", downloadFixed)

    log.Println("Starting server on :8080")
    _ = r.Run(":8080")
}

// Vulnerable handler: relies on a public share link without re-validating permissions
func downloadVulnerable(c *gin.Context) {
    shareID := c.Param("shareID")
    s, ok := shares[shareID]
    if !ok || !s.Active {
        c.Status(http.StatusNotFound)
        return
    }
    // Vulnerable: no re-check of the owner's current permissions
    c.File(s.FilePath)
}

// Fixed handler: performs real-time authorization checks
func downloadFixed(c *gin.Context) {
    shareID := c.Param("shareID")
    s, ok := shares[shareID]
    if !ok || !s.Active {
        c.Status(http.StatusNotFound)
        return
    }

    // Re-check owner's current permissions at access time
    ow, ok := owners[s.OwnerID]
    if !ok || !ow.Active || !ow.CanDownload {
        c.Status(http.StatusForbidden)
        return
    }

    c.File(s.FilePath)
}

CVE References

Choose which optional cookies to allow. You can change this any time.