Audiobookshelf is popular among self-hosters for managing audiobooks and podcasts at home, giving you a slick library and mobile streaming. But in early 2024, a security flaw landed between versions 2.17. and 2.19.1 that made your private collection a lot less private—and potentially put your whole server out of commission.
In this exclusive deep dive, we’ll walk through what CVE-2025-25205 actually is, why it happened, what attackers could do with it, and how you can check or fix your server. We’ll keep it simple and clear, with code snippets and links for those who want to dig deeper.
The Flaw: Unanchored Regex Lets Attackers Bypass Login Protections
Starting in v2.17., Audiobookshelf tried to check if API routes needed authentication using regex (regular expression) matches. But these regex checks weren’t strict—they weren’t “anchored”—which meant they’d match unintended places, like inside query parameters. That’s a problem, because a typical URL you want locked down like:
/api/items/1/cover
could actually be matched even if it appeared *anywhere* in the full URL string—even in places where no real user request would go.
How It Was Exploited
An attacker could send a GET request like this, with the dangerous route buried in a query string:
GET /api/public/search?r=/api/items/1/cover HTTP/1.1
Host: your.server
If Audiobookshelf’s authentication function looked like this
const protectedRegex = /\/api\/items\/\d+\/cover/;
if (protectedRegex.test(req.url)) {
// This should require authentication...
}
then even a URL with ?r=/api/items/1/cover *would pass the test*—even though the real path isn’t /api/items/1/cover!
That’s an *authentication bypass*: The system thinks it’s looking at a protected route, but thanks to a misplaced regex, you might not need to be logged in to get data.
Access private audiobook covers (or other media) without logging in
- Trigger server errors or crashes: Some endpoints expect a valid user. If you hit them unauthenticated and the code isn’t ready, the whole Audiobookshelf server can crash (DoS).
- Potential wider info disclosure: If more routes are matched, attackers might scrape more library info or files.
If you’re running a public Audiobookshelf site or expose it through proxies, this could be exploited directly from the internet.
Let’s see a quick *proof-of-concept*, using curl to grab a cover image that should be private
curl "http://your.server/api/public/search?r=/api/items/1/cover"; -o cover.jpg
This might succeed in leaking the file even if you require login—because of the dodgy regex match.
Or, to crash the server (DoS) by hitting a sensitive path without authentication
curl "http://your.server/api/public/search?r=/api/protected/needs-user";
If that route expects a valid user, and the object isn’t there, Audiobookshelf can throw an error and stop working—until someone restarts it.
Fixed in 2.19.1
The developers patched the issue by switching to strict regex matches anchored to the start of the path—and now *only the actual URL path* (not the query string) is matched.
Example fix (in pseudocode)
const protectedRegex = /^\/api\/items\/\d+\/cover/; // Note the ^ to anchor it!
if (protectedRegex.test(req.path)) {
// Now only real API paths those routes are protected
}
How to Stay Safe
- Update Immediately: Upgrade to Audiobookshelf 2.19.1 or newer from GitHub.
- Audit Your Exposure: If you had your server public-facing during this window, consider rotating credentials and watching for weird activity.
References
- Original Advisory: GitHub Security Advisory for CVE-2025-25205
- Release With Fix: Audiobookshelf v2.19.1 Release Notes
- CVE record: NVD CVE-2025-25205
Summary
CVE-2025-25205 shows how a small coding mistake (unanchored regex) can open up much bigger risks—letting anyone bypass authentication, view private files, or even crash the server. If you use Audiobookshelf, update to version 2.19.1 or later as soon as possible, and be careful with regular expressions in your own APIs.
Timeline
Published on: 02/12/2025 19:15:21 UTC