CVE-2026-49340 is a high-severity path traversal vulnerability in go.senan.xyz/gonic (go), affecting versions <= 0.20.1. It is fixed in 0.21.0.
Summary 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 the playlist ownership IDOR fixed in 6dd71e6: it is an unreachable guard clause combined with no path containment in Store.Write. Root cause, unreachable guard clause server/ctrlsubsonic/handlersplaylist.go:74-90: playlist.Store.Read (playlist/playlist.go:88-144) returns either (Playlist, nil) on success or (nil, err) on any failure path. There is no return path of (non-nil, non-nil-err). So the inner branch err != nil && pl != nil is always false, the playlist = pl assignment never executes, and playlist stays at its zero value with UserID = 0. The subsequent guard playlist.UserID != 0 && playlist.UserID != user.ID simplifies to false && (anything) and always passes, regardless of who owns the target path. Root cause, no path containment in Store.Write playlist/playlist.go:146-160: filepath.Join("/var/lib/gonic/playlists", "../../etc/cron.daily/anything") resolves to /var/lib/gonic/etc/cron.daily/anything, Go's filepath.Join does NOT prevent .. traversal. Combined with the missing guard above, any authenticated user controls the destination path. Live PoC, passing Go test Drop this into server/ctrlsubsonic/handlersplaylistwritetraversaltest.go and run go test -run TestCreatePlaylistArbitraryWriteRawPath ./server/ctrlsubsonic/ -v: Test output against current master HEAD 6dd71e6: The file was created at <tmp>/injected.m3u while the playlist store's basePath is <tmp>/playlists/, write succeeded outside the intended directory. HTTP-level reproduction Impact Integrity: Any authenticated user can overwrite (truncate-and-rewrite) any file the gonic process has write access to: gonic's own SQLite database, configuration files, log files, cache, audit trails, M3U files of other users. The write is M3U-structured (#GONIC-NAME: / #GONIC-COMMENT: / #GONIC-IS-PUBLIC: attributes, plus song paths), but the name value is attacker-controlled and structurally placed (no newline injection; strconv.Quote escapes specials). Availability: Overwriting gonic.db (or wherever the SQLite file lives) destroys all user state, accounts, ratings, playlists, etc. The write is unrecoverable. Filesystem state: MkdirAll(dir, 0o777) creates intermediate directories as world-writable, regardless of the umask, which is itself a hardening issue alongside the traversal. Trust boundary: gonic explicitly supports a non-admin user role (ServeCreateUser, the IsAdmin flag). This bug grants every non-admin user a destructive filesystem-write primitive into the host process's working set. Content control is structural (cannot inject newlines into the M3U attribute lines), so direct shell/web-shell injection requires a target file format that tolerates the #GONIC-NAME:"..." header. Pure-destructive primitives (overwrite/truncate, fill-by-mkdir) work universally. CVSS CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H = 8.1 High Suggested fix Two changes, either of which mitigates this: Fix the unreachable guard at handlers_playlist.go:83: This restores the ownership check for the case where the path resolves to an existing playlist. It does NOT fix the case where playlistPath points to a non-existent file (the Read fails, playlist stays zero-valued, ownership check still bypassed). So the second fix is also needed. Add path containment in playlist/playlist.go::Store.Write (same helper proposed in the companion advisory): Apply the same guard in Read() and Delete() to close related primitives. Consider tightening MkdirAll from 0o777 to 0o755. Credits Reported by Vishal Shukla (@shukla304 / @therawdev).
Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files. Typical impact: unauthorized file read or write outside the intended directory.
CVE-2026-49340 has a CVSS score of 8.1 (High). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment.
A fixed version is available (0.21.0). Upgrading removes the vulnerable code path.
go
go.senan.xyz/gonic (<= 0.20.1)go.senan.xyz/gonic → 0.21.0 (go)Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter instead of chasing every advisory.
Kodem's runtime-powered SCA identifies whether CVE-2026-49340 is reachable in your applications. Explore open-source security for your team.
See if CVE-2026-49340 is reachable in your applications. Get a demo
Already deployed Kodem? See CVE-2026-49340 in your environment →Upgrade go.senan.xyz/gonic to 0.21.0 or later to resolve this vulnerability.
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
CVE-2026-49340 is a high-severity path traversal vulnerability in go.senan.xyz/gonic (go), affecting versions <= 0.20.1. It is fixed in 0.21.0. Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files.
CVE-2026-49340 has a CVSS score of 8.1 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
go.senan.xyz/gonic (go) versions <= 0.20.1 is affected.
Yes. CVE-2026-49340 is fixed in 0.21.0. Upgrade to this version or later.
Whether CVE-2026-49340 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
Upgrade go.senan.xyz/gonic to 0.21.0 or later.