Navidrome allows SQL Injection via role parameter
Description
Navidrome is an open source web-based music collection server and streamer. Versions 0.55.0 through 0.55.2 have a vulnerability due to improper input validation on the role parameter within the API endpoint /api/artist. Attackers can exploit this flaw to inject arbitrary SQL queries, potentially gaining unauthorized access to the backend database and compromising sensitive user information. Version 0.56.0 contains a patch for the issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Improper input validation on the 'role' parameter in Navidrome's /api/artist endpoint allows SQL injection, potentially exposing sensitive user data.
Vulnerability
Navidrome versions 0.55.0 through 0.55.2 are vulnerable to SQL injection due to improper input validation on the role parameter within the /api/artist endpoint [1]. The role parameter is used to filter artists by role (e.g., artist, composer), but lacks sanitization, allowing an attacker to inject arbitrary SQL queries.
Exploitation
An attacker can exploit this flaw by sending a crafted HTTP request to the /api/artist endpoint with a malicious role parameter [4]. For example, a payload such as albumartist') UNION ALL SELECT ... can be used to extract database contents. The vulnerability does not require authentication, though the endpoint may be accessible only to users with network access to the Navidrome server.
Impact
Successful exploitation allows an attacker to execute arbitrary SQL queries on the backend database [1]. This could lead to unauthorized access to sensitive user information, including credentials and personal data stored by the music server [1].
Mitigation
The issue has been patched in version 0.56.0 [1]. The fix introduces an allowlist validation for the role parameter, rejecting any unexpected input [3]. Users are strongly advised to upgrade to the latest version. No workarounds are available.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/navidrome/navidromeGo | >= 0.55.0, < 0.56.0 | 0.56.0 |
Affected products
2- navidrome/navidromev5Range: >= 0.55.0, < 0.56.0
Patches
1b19d5f0d3e07Merge commit from fork
2 files changed · +28 −1
persistence/artist_repository.go+6 −1 modified@@ -129,7 +129,12 @@ func NewArtistRepository(ctx context.Context, db dbx.Builder) model.ArtistReposi } func roleFilter(_ string, role any) Sqlizer { - return NotEq{fmt.Sprintf("stats ->> '$.%v'", role): nil} + if role, ok := role.(string); ok { + if _, ok := model.AllRoles[role]; ok { + return NotEq{fmt.Sprintf("stats ->> '$.%v'", role): nil} + } + } + return Eq{"1": 2} } func (r *artistRepository) selectArtist(options ...model.QueryOptions) SelectBuilder {
persistence/artist_repository_test.go+22 −0 modified@@ -321,4 +321,26 @@ var _ = Describe("ArtistRepository", func() { }) }) }) + + Describe("roleFilter", func() { + It("filters out roles not present in the participants model", func() { + Expect(roleFilter("", "artist")).To(Equal(squirrel.NotEq{"stats ->> '$.artist'": nil})) + Expect(roleFilter("", "albumartist")).To(Equal(squirrel.NotEq{"stats ->> '$.albumartist'": nil})) + Expect(roleFilter("", "composer")).To(Equal(squirrel.NotEq{"stats ->> '$.composer'": nil})) + Expect(roleFilter("", "conductor")).To(Equal(squirrel.NotEq{"stats ->> '$.conductor'": nil})) + Expect(roleFilter("", "lyricist")).To(Equal(squirrel.NotEq{"stats ->> '$.lyricist'": nil})) + Expect(roleFilter("", "arranger")).To(Equal(squirrel.NotEq{"stats ->> '$.arranger'": nil})) + Expect(roleFilter("", "producer")).To(Equal(squirrel.NotEq{"stats ->> '$.producer'": nil})) + Expect(roleFilter("", "director")).To(Equal(squirrel.NotEq{"stats ->> '$.director'": nil})) + Expect(roleFilter("", "engineer")).To(Equal(squirrel.NotEq{"stats ->> '$.engineer'": nil})) + Expect(roleFilter("", "mixer")).To(Equal(squirrel.NotEq{"stats ->> '$.mixer'": nil})) + Expect(roleFilter("", "remixer")).To(Equal(squirrel.NotEq{"stats ->> '$.remixer'": nil})) + Expect(roleFilter("", "djmixer")).To(Equal(squirrel.NotEq{"stats ->> '$.djmixer'": nil})) + Expect(roleFilter("", "performer")).To(Equal(squirrel.NotEq{"stats ->> '$.performer'": nil})) + + Expect(roleFilter("", "wizard")).To(Equal(squirrel.Eq{"1": 2})) + Expect(roleFilter("", "songanddanceman")).To(Equal(squirrel.Eq{"1": 2})) + Expect(roleFilter("", "artist') SELECT LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))--")).To(Equal(squirrel.Eq{"1": 2})) + }) + }) })
Vulnerability mechanics
Generated 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-5wgp-vjxm-3x2rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-48949ghsaADVISORY
- github.com/navidrome/navidrome/commit/b19d5f0d3e079639904cac95735228f445c798b6ghsax_refsource_MISCWEB
- github.com/navidrome/navidrome/security/advisories/GHSA-5wgp-vjxm-3x2rghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.