VYPR
Unrated severityNVD Advisory· Published Jun 19, 2026

gonic has arbitrary file write in createPlaylist: any authenticated user can write playlist M3U content to attacker-controlled path on the host

CVE-2026-49340

Description

gonic is a music streaming server / free-software subsonic server API implementation. Prior to version 0.21.0, a logic error in ServeCreateOrUpdatePlaylist allows any authenticated Subsonic user (including non-admin) to write playlist M3U content to an attacker-controlled absolute filesystem path on the gonic host, and to create intermediate directories with 0o777 permissions. The bug is independent of CVE-2026-49338 and CVE-2026-49339. It is an unreachable guard clause combined with no path containment in Store.Write. Version 0.21.0 patches the issue.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected products

1

Patches

Vulnerability mechanics

Root cause

"Missing input validation: an unreachable guard clause in `ServeCreateOrUpdatePlaylist` bypasses ownership checks, and `Store.Write` does not sanitize `..` sequences in the playlist path."

Attack vector

An authenticated non-admin Subsonic user sends a `createPlaylist` API request with a crafted `id` parameter whose base64-decoded value contains `../` sequences (e.g., `pl -../../../var/log/anything.log`). The unreachable guard causes the owner check to always pass [ref_id=1]. `Store.Write` resolves the traversal via `filepath.Join`, creating the M3U file (and intermediate directories with `0o777` permissions) at an attacker-controlled absolute path [ref_id=1]. The write is M3U-structured but the `name` field is attacker-controlled, enabling overwrite of any file the gonic process can write.

Affected code

`server/ctrlsubsonic/handlers_playlist.go:74-90` contains an unreachable guard clause—`Store.Read` never returns `(non-nil, non-nil-err)`, so the ownership check `playlist.UserID != 0 && playlist.UserID != user.ID` is always bypassed. Additionally, `playlist/playlist.go:146-160` (`Store.Write`) uses `filepath.Join` without any path-containment check, allowing `..` traversal to escape the base directory.

What the fix does

The patch fixes two root causes found in the advisory [ref_id=1]. First, in `handlers_playlist.go:83`, the condition `err != nil && pl != nil` is corrected to `err == nil && pl != nil` so the ownership guard actually executes when a playlist is read successfully. Second, in `playlist/playlist.go`, a path-containment check is added after `filepath.Join`: computing the relative path from `basePath` and rejecting the write if the resolved path escapes the intended playlist directory. The same sanitization should also be applied to `Read()` and `Delete()`. Together these changes prevent both the logic bypass and the directory traversal.

Preconditions

  • authValid Subsonic user account (non-admin role is sufficient)
  • networkNetwork access to the gonic server's HTTP API
  • inputAttacker controls the `id` parameter in a `createPlaylist` request, encoding a directory-traversal payload

Reproduction

See ref_id=1 for a Go test (`TestCreatePlaylistArbitraryWrite_RawPath`) and a curl example that write a file outside the intended playlist directory via a traversal payload.

Generated on Jun 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

1

News mentions

0

No linked articles in our index yet.