CVE-2026-54493
Summary
Koel v9.6.0 validates radio station URLs on the regular web API, but the Subsonic-compatible radio endpoints do not apply the same SSRF protections. An authenticated user can create or update a radio station with a private URL and then use Koel's radio streaming feature to make the server fetch that URL and return the upstream response body.
This was validated against v9.6.0 (352ea5ec27fa22294da8fb6beacb3d5552f0d09c) using the official phanan/koel:9.6.0 image.
Details
SafeUrl is applied on the web API, but not on the Subsonic endpoints
Koel's regular radio API protects station URLs with SafeUrl and HasAudioContentType:
- app/Http/Requests/API/Radio/RadioStationStoreRequest.php
- app/Http/Requests/API/Radio/RadioStationUpdateRequest.php
new SafeUrl(),
new HasAudioContentType(),
The Subsonic-compatible routes do not reuse those checks:
- routes/subsonic.php
- createInternetRadioStation.view
- updateInternetRadioStation.view
- app/Http/Requests/Subsonic/CreateInternetRadioStationRequest.php
- app/Http/Requests/Subsonic/UpdateInternetRadioStationRequest.php
return [
'streamUrl' => ['required', 'string'],
'name' => ['required', 'string'],
'homepageUrl' => ['nullable', 'string'],
];
The result is a validation gap between two routes that create the same type of object.
The unvalidated URL is stored and later fetched server-side
The Subsonic controllers hand the supplied URL to the regular radio service without any SSRF validation:
- app/Http/Controllers/Subsonic/CreateInternetRadioStationController.php
- app/Http/Controllers/Subsonic/UpdateInternetRadioStationController.php
- app/Services/RadioService.php
The SSRF is triggered when the station is played:
- app/Http/Controllers/StreamRadioController.php
- app/Services/Radio/RadioStreamService.php
- app/Services/Radio/RadioStreamProxy.php
RadioStreamProxy::openStream() opens a web address supplied by the attacker (attacker-controlled URL) without proper checks:
$stream = fopen($url, 'r', false, $conte
⚡ Watch CVE-2026-54493
Get an email if CVE-2026-54493 is added to CISA KEV, gains public exploit code, or a new advisory cites it — max one per day, one-click unsubscribe.
Advisory coverage (1)
External references
Embed the live status
— this badge updates automatically when the KEV or exploit status changes. How to embed it →
[](https://www.csirts.com/cve/CVE-2026-54493)