CVE-2026-54492
PHP vulnerability analysis and mitigation

Overview

CVE-2026-54492 is an authenticated blind Server-Side Request Forgery (SSRF) vulnerability in Koel, an open-source personal music streaming server. The flaw exists in the Subsonic-compatible createPodcastChannel.view route, which lacks the SafeUrl validation applied to the regular podcast subscription API, allowing an authenticated user to cause the server to fetch arbitrary internal URLs during podcast channel creation. It affects Koel versions up to and including v9.6.0 (Composer package phanan/koel), and was fixed in v9.7.0. The vulnerability was first published on June 4, 2026, and carries a CVSS v3.1 base score of 4.3 (Medium) (GitHub Advisory, Koel Advisory).

Technical details

The root cause is a trust-boundary mismatch (CWE-918) between Koel's regular web API and its Subsonic-compatible API layer. The regular podcast endpoint (app/Http/Requests/API/Podcast/PodcastStoreRequest.php) enforces new SafeUrl() on the url field, blocking private/internal destinations. However, the Subsonic route (app/Http/Requests/Subsonic/CreatePodcastChannelRequest.php) only validates ['required', 'string', 'url'], omitting the SafeUrl check entirely. When a request reaches CreatePodcastChannelController, it calls PodcastService::addPodcast(), which immediately invokes createParser($url)Poddle::fromUrl($url, 5 * 60, $this->client), triggering a server-side HTTP fetch to the attacker-supplied URL with no further validation. A public PoC is included in the advisory, demonstrating exploitation against the official phanan/koel:9.6.0 Docker image (GitHub Advisory, Fix PR).

Impact

An authenticated attacker can cause the Koel server to issue HTTP requests to internal network destinations — including loopback addresses, Docker bridge networks, and RFC1918 ranges — that are explicitly blocked by the main API. This enables internal service discovery and request execution through the podcast parser. While generic response-body exfiltration was not confirmed through this specific route, the SSRF primitive could be used to probe internal infrastructure, interact with metadata services (e.g., cloud instance metadata endpoints), or pivot to other internal services reachable from the Koel host (Koel Advisory).

Exploitability

A working PoC is publicly documented in the GitHub Security Advisory, requiring only valid Koel credentials and a Subsonic API key — both obtainable by any registered user. No elevated privileges beyond a standard authenticated account are needed. The CVE status is listed as Reserved and there is no evidence of in-the-wild exploitation or threat actor attribution at this time. The vulnerability is not listed in the CISA KEV catalog. No EPSS score is currently available (GitHub Advisory).

Exploitation steps

  1. Authenticate to Koel: Obtain a bearer token by POSTing credentials to /api/me (e.g., curl -X POST http://<koel-host>/api/me -d '{"email":"user@example.com","password":"password"}').
  2. Retrieve Subsonic API key: Fetch the current user's Subsonic API key from /api/data using the bearer token (curl http://<koel-host>/api/data -H 'Authorization: Bearer <token>' and extract current_user.subsonic_api_key).
  3. Identify internal target: Determine an internal URL to probe (e.g., http://172.17.0.1:8080/internal-service, http://169.254.169.254/latest/meta-data/, or http://127.0.0.1:<port>/).
  4. Verify the regular API blocks the URL: Confirm the main API rejects the target with HTTP 422 by POSTing to /api/podcasts with the internal URL — this validates the SSRF bypass is needed.
  5. Trigger SSRF via Subsonic route: Send a GET request to /rest/createPodcastChannel.view with the apiKey, f=json, and url=<internal-target> parameters. The server will immediately fetch the internal URL as part of podcast channel creation and return HTTP 200 with "status":"ok".
  6. Confirm server-side request: Monitor the internal target service's access logs to confirm the Koel server issued HEAD and GET requests to the specified URL (GitHub Advisory, Koel Advisory).

Indicators of compromise

  • Network: Unexpected outbound HTTP requests (HEAD and GET) from the Koel server to internal IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16) or Docker bridge addresses (172.17.0.0/16).
  • Logs: Koel web server access logs showing GET requests to /rest/createPodcastChannel.view with url parameters containing private/RFC1918 addresses or loopback URLs; internal service access logs showing requests originating from the Koel server's IP with podcast-parser user-agent strings.
  • Application Logs: Laravel application logs (storage/logs/laravel.log) showing FailedToParsePodcastFeedException or connection errors to internal hosts, indicating attempted SSRF fetches that failed due to service unavailability.

Mitigation and workarounds

Upgrade to Koel v9.7.0 or later, which applies SafeUrl validation to the CreatePodcastChannelRequest and adds defense-in-depth checks in PodcastService::createParser() that throw a dedicated UnsafePodcastFeedUrlException before passing any URL to Poddle::fromUrl(). The fix was merged via PR #2545 and released on June 4, 2026. No configuration-based workaround is available for unpatched versions; restricting access to the /rest/ Subsonic API endpoints at the network or reverse-proxy level can reduce exposure until an upgrade is possible (Koel v9.7.0 Release, Fix PR).

Community reactions

The vulnerability was discovered by security researcher dennyabrahamsinaga and responsibly disclosed to the Koel maintainer (phanan), who published the advisory and merged the fix on June 3–4, 2026. The fix was noted to also address a related SSRF in the Subsonic internet radio endpoints (GHSA-6p96-cfg5-4vhp), and a follow-up PR (#2546) was merged to validate redirect hops on outbound HTTP to prevent redirect-based SSRF bypasses flagged during code review (Koel Advisory, Fix PR).

Additional resources


SourceThis report was generated using AI

Related PHP vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-54493HIGH7.7
  • PHP logoPHP
  • phanan/koel
NoYesAug 19, 2026
CVE-2026-54491HIGH7.1
  • PHP logoPHP
  • phanan/koel
NoYesAug 19, 2026
CVE-2026-61807MEDIUM6.3
  • PHP logoPHP
  • snipe/snipe-it
NoYesAug 19, 2026
CVE-2026-54494MEDIUM5.3
  • PHP logoPHP
  • phanan/koel
NoYesAug 19, 2026
CVE-2026-54492MEDIUM4.3
  • PHP logoPHP
  • phanan/koel
NoYesAug 19, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management