VYPR
High severityNVD Advisory· Published May 30, 2025· Updated May 30, 2025

Navidrome allows SQL Injection via role parameter

CVE-2025-48949

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.

PackageAffected versionsPatched versions
github.com/navidrome/navidromeGo
>= 0.55.0, < 0.56.00.56.0

Affected products

2
  • Range: >=0.55.0, <=0.55.2
  • navidrome/navidromev5
    Range: >= 0.55.0, < 0.56.0

Patches

1
b19d5f0d3e07

Merge commit from fork

https://github.com/navidrome/navidromeCaio CottsMay 28, 2025via ghsa
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

News mentions

0

No linked articles in our index yet.