CVE-2026-50552 Overview
CVE-2026-50552 is a Server-Side Request Forgery (SSRF) vulnerability in Koel, a free and open-source music streaming solution. The flaw exists in the radio station creation endpoint (POST /api/radio/stations) in versions prior to 9.7.1. The url field validation rules omit the bail keyword, so the HasAudioContentType rule continues to execute even after the SafeUrl rule rejects a URL pointing to a private or reserved address. Any authenticated, non-admin user can coerce the server into issuing HEAD or GET requests to arbitrary internal hosts. The issue is tracked under [CWE-918] and was patched in version 9.7.1.
Critical Impact
Authenticated low-privilege users can pivot through the Koel server to reach internal services, metadata endpoints, and other reserved network ranges.
Affected Products
- Koel music streaming solution versions prior to 9.7.1
- Self-hosted Koel deployments exposing the radio station API
- Koel instances accessible to non-admin authenticated users
Discovery Timeline
- 2026-06-12 - CVE-2026-50552 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-50552
Vulnerability Analysis
Koel exposes a radio station creation endpoint that accepts a url field. The endpoint applies a Laravel validation chain that includes a custom SafeUrl rule and a HasAudioContentType rule. The SafeUrl rule resolves the host and rejects URLs that point to private, loopback, or reserved address ranges. The HasAudioContentType rule issues an outbound HTTP request to verify the response content type.
Because the validator omits the bail keyword, Laravel continues evaluating subsequent rules after a prior rule fails. When SafeUrl rejects a private address, the HasAudioContentType rule still fires and performs the HTTP request anyway. The server then issues HEAD or GET requests against attacker-controlled URLs, including internal services, cloud metadata endpoints, and other hosts that are otherwise unreachable.
Root Cause
The root cause is missing short-circuit validation. Laravel evaluates validation rules sequentially but does not stop on first failure unless the bail rule is present. The original rule set declared required and url checks alongside SafeUrl and HasAudioContentType, but never told the validator to stop. The fix prepends bail to the rule array so that failure of SafeUrl prevents HasAudioContentType from running.
Attack Vector
An authenticated, non-admin user submits a POST /api/radio/stations request with a url value pointing to an internal resource such as http://127.0.0.1, http://169.254.169.254/latest/meta-data/, or an IPv6 link-local address. Although the API returns a validation error, the server still issues an outbound request to the supplied URL, enabling reconnaissance of internal infrastructure and interaction with services that trust the Koel host.
$validator = Validator::make(['url' => $request['url']], [
'url' => [
+ 'bail',
'required',
'url',
Rule::unique('radio_stations')->where(static fn (Builder $query) => $query->where('user_id', $userId)),
// ... SafeUrl and HasAudioContentType rules follow
],
]);
// Source: https://github.com/koel/koel/commit/5f6ce2cefd08f437a269236b677ad971517ccbb6
The patch adds bail so validation halts on the first failed rule, preventing HasAudioContentType from making the outbound request after SafeUrl rejects the host.
Detection Methods for CVE-2026-50552
Indicators of Compromise
- Outbound HEAD or GET requests from the Koel application server to RFC1918, loopback, or link-local addresses
- Repeated POST /api/radio/stations requests from non-admin accounts that return validation errors
- Application logs showing HasAudioContentType rule execution against URLs that also triggered SafeUrl failures
- Outbound requests to cloud metadata endpoints such as 169.254.169.254 from the Koel host
Detection Strategies
- Inspect web access logs for POST /api/radio/stations activity correlated with internal-host destinations in egress logs
- Hunt for outbound HTTP requests originating from the Koel application user-agent toward non-routable ranges
- Alert on validation failure responses paired with successful outbound DNS resolution of the submitted hostname
Monitoring Recommendations
- Forward Koel application logs and host network telemetry to a centralized analytics platform for correlation
- Monitor egress traffic from the Koel server using deny-by-default rules and alert on policy violations
- Track per-user request rates against /api/radio/stations to identify scanning behavior
How to Mitigate CVE-2026-50552
Immediate Actions Required
- Upgrade Koel to version 9.7.1 or later, which adds the bail rule and removes vulnerable network helpers
- Restrict outbound network access from the Koel application server using egress firewall rules
- Revoke or audit non-admin accounts created during the exposure window and review radio station entries
- Block access to cloud metadata endpoints from the Koel host with explicit deny rules
Patch Information
The fix is included in Koel 9.7.1. See the GitHub Security Advisory and the GitHub Commit Details for the complete change set, which also addresses related DNS rebinding and IPv6 transition issues.
Workarounds
- Place the Koel server behind an egress proxy that enforces an allowlist of permitted destinations
- Disable or restrict the radio station feature for non-admin users until patching is complete
- Block outbound traffic from the Koel host to RFC1918, loopback, link-local, and IPv6 reserved ranges
# Example iptables egress restriction for the Koel host
iptables -A OUTPUT -d 127.0.0.0/8 -j REJECT
iptables -A OUTPUT -d 10.0.0.0/8 -j REJECT
iptables -A OUTPUT -d 172.16.0.0/12 -j REJECT
iptables -A OUTPUT -d 192.168.0.0/16 -j REJECT
iptables -A OUTPUT -d 169.254.0.0/16 -j REJECT
ip6tables -A OUTPUT -d ::1/128 -j REJECT
ip6tables -A OUTPUT -d fc00::/7 -j REJECT
ip6tables -A OUTPUT -d fe80::/10 -j REJECT
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

