Jul 15, 2026·6 min read·4 visits
A missing validation halt keyword allows Koel's HTTP client to initiate connection probes to internal and loopback IP addresses even after the URL is marked unsafe.
An authenticated Server-Side Request Forgery (SSRF) vulnerability in Koel, an open-source personal music streaming server, allows remote attackers to probe internal hosts and loopback addresses. The vulnerability arises due to a missing 'bail' validation rule in the Laravel-based form validation pipeline, which permits downstream HTTP checks to execute even after a URL has failed security verification.
Koel is an open-source personal music streaming server designed using the Laravel PHP framework. To support external streams, Koel implements features allowing users to create and edit internet radio stations. This capability is exposed through endpoint routes like /api/radio/stations and equivalent Subsonic integration endpoints. These operations require the application to process remote URLs to locate live audio feeds.
The core attack surface resides within the server-side validation mechanics of these radio endpoint controllers. When an authenticated, non-administrative user registers or updates an external radio station URL, Koel runs the payload through a sequence of input-checking rules. This sequence is intended to verify both host safety and media compatibility.
The vulnerability (CVE-2026-50552) is classified as a Server-Side Request Forgery (SSRF) representing CWE-918. Because of a logic gap in the validation pipeline, an attacker can coerce Koel's HTTP engine into establishing connection attempts with arbitrary hosts, including local loopback interfaces and internal network resources.
The root cause of CVE-2026-50552 stems from the configuration of Laravel's multi-rule validation framework. Laravel validation rule sets execute sequentially inside an array. Under default settings, if one validator rule fails, Laravel does not stop executing the remaining rules. Instead, it proceeds through the entire list to collect all possible validation errors to report back to the client interface.
In vulnerable versions of Koel, the array contains the SafeUrl rule and the HasAudioContentType rule in immediate succession. The SafeUrl rule resolves the user-provided domain and verifies whether it maps to a private range like 127.0.0.1, 10.0.0.0/8, or cloud metadata networks such as 169.254.169.254. If an attacker supplies an internal address, the rule correctly detects the threat and logs a validation error.
Because the 'bail' rule is omitted from the validation rule list, Laravel does not abort validation upon this failure. It immediately proceeds to evaluate the next rule in the queue, which is HasAudioContentType. The HasAudioContentType rule sends out an outbound HTTP request using Guzzle to verify if the stream URL has a valid media content type. This sequence results in an outbound request being dispatched to the forbidden target address before the validation transaction can be terminated.
In vulnerable versions, requests such as CreateInternetRadioStationRequest and RadioStationStoreRequest failed to enforce early termination during validation. Below is the vulnerable validation configuration array:
// Vulnerable Configuration
public function rules(): array
{
return [
'streamUrl' => ['required', 'url', new SafeUrl(), new HasAudioContentType()],
'name' => ['required', 'string'],
'homepageUrl' => ['nullable', 'string'],
];
}The patch introduces the 'bail' rule as the first element of the validation array. This halts execution of subsequent rules as soon as any preceding rule fails validation. Below is the updated code showing the patch application:
// Patched Configuration (Commit 5f6ce2cefd08f437a269236b677ad971517ccbb6)
public function rules(): array
{
return [
// The 'bail' keyword stops execution immediately upon SafeUrl failure
'streamUrl' => ['bail', 'required', 'url', new SafeUrl(), new HasAudioContentType()],
'name' => ['required', 'string'],
'homepageUrl' => ['nullable', 'string'],
];
}The patch also hardens the system against advanced SSRF risks such as DNS Rebinding. During a DNS Rebinding attack, an attacker-controlled nameserver responds with a short TTL, yielding a public IP during the SafeUrl check and then a loopback IP during the HTTP client request. To defeat this, Koel's security patch introduces IP pinning inside the SafeHttp network helper, forcing the underlying cURL client to resolve solely to the validated IP via the CURLOPT_RESOLVE option.
To exploit this vulnerability, an attacker must first obtain valid user credentials. This vulnerability does not require administrative permissions, making any regular account sufficient to execute the attack. After logging in, the attacker transmits a structured POST payload to the radio station creation endpoints.
The attacker targets internal infrastructure hosts by altering the port and host values within the URL parameter. The target application then serves as a request oracle. The server reacts differentially based on connection success or failure, allowing the attacker to distinguish between open and closed ports inside the target network.
An open port running an HTTP service yields a specific response, indicating that the URL is not a valid radio station URL. Conversely, closed ports or unresponsive IP addresses trigger connection timeouts or rejection exceptions, which the server returns as "The url couldn't be reached.". By analyzing these error responses, the attacker can systematically map the local loopback space and the private network hosting the Koel instance.
The direct impact of CVE-2026-50552 is local network mapping and service interaction. This vulnerability effectively transforms the Koel host into a proxy for internal network port scanning. This allows attackers to bypass boundary firewalls that separate the public-facing application server from private internal networks.
Attackers can target internal diagnostic endpoints, administrative consoles, and local microservices such as Redis, Memcached, or Kubernetes API servers. While the HTTP client first attempts a HEAD request, it falls back to a streaming GET request. Depending on the exposed services, this capability can allow attackers to issue command requests or extract sensitive metadata.
The vulnerability holds a CVSS v3.1 score of 6.3 (Medium Severity). The vulnerability scope remains unchanged because the requested execution occurs within the security parameters of the Koel web server itself. However, in environments lacking container-level segregation, the exploitation of this bug can lead to information disclosure or remote command delivery on unauthenticated internal services.
The primary remediation path is upgrading the Koel installation to version 9.7.1 or higher. This update applies the essential validation changes and establishes the network-level IP pinning mechanism. Administrators can pull the updated branch directly from the official repository and rebuild dependencies using Composer.
In environments where an immediate upgrade is not feasible, administrators can apply defensive configuration controls. Web Application Firewalls (WAF) should be configured to intercept traffic directed at /api/radio/stations and relevant Subsonic routes. The WAF must inspect input payloads for local loopback patterns, private RFC 1918 subnets, and cloud instance metadata addresses.
Additionally, network-level segregation should be enforced. The hosting server's egress policy should restrict outbound traffic. Specifically, the application runtime user must be denied outbound access to internal subnets and localhost administration ports except where explicitly required for database operations.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Koel koel | < 9.7.1 | 9.7.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 (Server-Side Request Forgery) |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 6.3 (Medium) |
| EPSS Score | 0.0016 |
| EPSS Percentile | 5.55% |
| Exploit Status | Proof of Concept / Public Details Available |
| CISA KEV Status | Not Listed |
The web application receives a URL or similar vector from an upstream component and retrieves the contents of this URL without sufficiently validating that the target is safe.
A Server-Side Request Forgery (SSRF) vulnerability in the open-source personal music streaming server Koel allows authenticated Subsonic API users to perform unauthorized network queries. This flaw resides in both the Subsonic podcast feed import routine and the subsequent redirect handling inside the podcast streaming helper, exposing private local networks and internal loopback systems to unauthorized reconnaissance and interaction.
CVE-2026-50661 is a security feature bypass vulnerability in Microsoft Windows BitLocker full-disk encryption. A physical attacker can exploit this flaw to bypass encryption controls, permitting unauthorized access to sensitive local storage and the modification of offline system configurations.
CVE-2026-56164 is a critical vulnerability affecting Microsoft SharePoint Server. It permits unauthenticated, remote attackers to bypass identity verification controls. This flaw is classified under CWE-306: Missing Authentication for Critical Function and allows elevation of privilege up to Farm Administrator level. The vulnerability has been added to CISA's Known Exploited Vulnerabilities catalog due to active exploitation.
A high-severity input sanitization and header injection vulnerability in TsDProxy allows authenticated Tailscale users to inject arbitrary values into the X-Forwarded-For and X-Real-IP HTTP headers. Because downstream backend services frequently trust these headers to resolve client identities, attackers can exploit this flaw to bypass IP-based access control lists, audit logs, and geo-blocking restrictions.
CVE-2026-54448 is a critical denial of service vulnerability in Trivy's Infrastructure-as-Code (IaC) misconfiguration scanning engine. Prior to version 0.71.0, Trivy utilized a custom archive parser to unpack Helm chart tarballs (.tgz) during automated scans. This custom implementation iterated through compressed files and loaded their entire raw contents into system memory using the io.ReadAll function without implementing size limits or threshold checks, enabling an attacker to trigger an immediate heap-allocation crash or system Out-of-Memory (OOM) termination using a decompression bomb.
A critical remote code execution vulnerability exists in TidGi Desktop up to version 0.13.0. The flaw allows an attacker to execute arbitrary code with Node.js privileges when a user imports or clones a malicious TiddlyWiki repository. This occurs due to the automatic execution of 'startup' modules defined in user-imported tiddler files.