Moderate severityOSV Advisory· Published Jan 8, 2026· Updated Jan 8, 2026
Soft Serve is missing an authorization check in LFS lock deletion
CVE-2026-22253
Description
Soft Serve is a self-hostable Git server for the command line. Prior to version 0.11.2, an authorization bypass in the LFS lock deletion endpoint allows any authenticated user with repository write access to delete locks owned by other users by setting the force flag. The vulnerable code path processes force deletions before retrieving user context, bypassing ownership validation entirely. This issue has been patched in version 0.11.2.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/charmbracelet/soft-serveGo | < 0.11.2 | 0.11.2 |
Affected products
1- Range: v0.1.0, v0.1.1, v0.1.2, …
Patches
1000ab5164f0bMerge commit from fork
1 file changed · +21 −11
pkg/web/git_lfs.go+21 −11 modified@@ -893,7 +893,6 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) { return } - // Delete another user's lock l := lfs.Lock{ ID: strconv.FormatInt(lock.ID, 10), Path: lock.Path, @@ -902,7 +901,27 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) { Name: owner.Username, }, } + + // Retrieve user context first for authorization checks + user := proto.UserFromContext(ctx) + if user == nil { + logger.Error("error getting user from context") + renderJSON(w, http.StatusUnauthorized, lfs.ErrorResponse{ + Message: "unauthorized", + }) + return + } + + // Force delete another user's lock (requires admin privileges) if req.Force { + if !user.IsAdmin() { + logger.Error("non-admin user attempted force delete", "user", user.Username()) + renderJSON(w, http.StatusForbidden, lfs.ErrorResponse{ + Message: "admin access required for force delete", + }) + return + } + if err := datastore.DeleteLFSLock(ctx, dbx, repo.ID(), lockID); err != nil { logger.Error("error deleting lock", "err", err) renderJSON(w, http.StatusInternalServerError, lfs.ErrorResponse{ @@ -915,16 +934,7 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) { return } - // Delete our own lock - user := proto.UserFromContext(ctx) - if user == nil { - logger.Error("error getting user from context") - renderJSON(w, http.StatusUnauthorized, lfs.ErrorResponse{ - Message: "unauthorized", - }) - return - } - + // Delete our own lock - verify ownership if owner.ID != user.ID() { logger.Error("error deleting another user's lock") renderJSON(w, http.StatusForbidden, lfs.ErrorResponse{
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-6jm8-x3g6-r33jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-22253ghsaADVISORY
- github.com/charmbracelet/soft-serve/commit/000ab5164f0be68cf1ea6b6e7227f11c0e388a42ghsax_refsource_MISCWEB
- github.com/charmbracelet/soft-serve/security/advisories/GHSA-6jm8-x3g6-r33jghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.