CVE-2026-100854
AzuraCast before 0.23.6 Metadata Injection via Liquidsoap API
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.3
AzuraCast before 0.23.6 Metadata Injection via Liquidsoap API
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
- Record
CVE-2026-100854- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N - CVSS 3.1
- 6.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-87834
5.3
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
- Record
EUVD-2026-87834- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4fm3-ggg2-c6qx
6.3
AzuraCast's Missing RequireInternalConnection on Liquidsoap API Allows Low-Privilege Metadata Injection and Broadcast Disruption
Summary
The /api/internal/{station_id}/liquidsoap/{action} endpoint is accessible from the public web interface because it lacks the RequireInternalConnection middleware that protects other internal endpoints (/sftp-auth, /sftp-event). Combined with a logic flaw where the $asAutoDj flag is set based on the presence of the X-Liquidsoap-Api-Key header rather than its validated value, any user with the basic View station permission can invoke privileged Liquidsoap commands — injecting arbitrary now-playing metadata visible to all listeners, disrupting live broadcast tracking, and disclosing absolute filesystem paths.
Details
Issue 1: Missing RequireInternalConnection middleware
In backend/config/routes/api_internal.php, the liquidsoap route group (lines 17-21) lacks the RequireInternalConnection middleware:
// Lines 17-21 — NO RequireInternalConnection
$group->map(
['GET', 'POST'],
'/liquidsoap/{action}',
Controller\Api\Internal\LiquidsoapAction::class
)->setName('api:internal:liquidsoap');
Compare with sftp endpoints that correctly apply it:
// Lines 32-34 — HAS RequireInternalConnection
$group->post('/sftp-auth', Controller\Api\Internal\SftpAuthAction::class)
->setName('api:internal:sftp-auth')
->add(Middleware\RequireInternalConnection::class);
The nginx config (util/docker/web/nginx/azuracast.conf.tmpl) only sets the IS_INTERNAL FastCGI parameter on the internal port 6010 listener (line 44), not on the public-facing server block (ports 80/443). Without the middleware, the endpoint is fully accessible from the public internet.
Issue 2: $asAutoDj derived from header presence, not validated value
In backend/src/Controller/Api/Internal/LiquidsoapAction.php:
// Line 34 — checks header PRESENCE, not value
$asAutoDj = $request->hasHeader('X-Liquidsoap-Api-Key');
// Lines 38-44 — key value only checked when ACL FAILS
$acl = $request->getAcl();
if (!$acl->isAllowed(StationPermissions::View, $station->id)) {
$authKey = $request->getHeaderLine('X-Liquidsoap-Api-Key');
if (!$station->validateAdapterApiKey($authKey)) {
throw new RuntimeException('Invalid API key.');
}
}
When a user authenticates via session/API key and has StationPermissions::View, the ACL check passes and the adapter API key is never validated. But $asAutoDj is already true from line 34 because the header is present (with any arbitrary value).
Affected commands:
FeedbackCommand(backend/src/Radio/Backend/Liquidsoap/Command/FeedbackCommand.php:36): Guardif (!$asAutoDj) return false;bypassed — creates SongHistory records and forces NowPlaying cache updatesDjOffCommand(backend/src/Radio/Backend/Liquidsoap/Command/DjOffCommand.php:24): Guard bypassed — calls$this->streamerRepo->onDisconnect($station)which ends all active broadcasts and sets$station->is_streamer_live = falseDjOnCommand(backend/src/Radio/Backend/Liquidsoap/Command/DjOnCommand.php:31): Guard bypassed — calls$this->streamerRepo->onConnect($station, $user)with attacker-controlled usernameCopyCommand(backend/src/Radio/Backend/Liquidsoap/Command/CopyCommand.php:18): No$asAutoDjguard at all — returns absolute filesystem paths via$mediaFs->getLocalPath($uri)
PoC
Prerequisites: A user account with StationPermissions::View on station ID 1 (the lowest station-level permission). Obtain a session cookie or API key for this user.
1. Inject arbitrary now-playing metadata (FeedbackCommand):
curl -X POST 'https://target/api/internal/1/liquidsoap/feedback' \
-H 'X-API-Key: <view-user-api-key>' \
-H 'X-Liquidsoap-Api-Key: anything' \
-H 'Content-Type: application/json' \
-d '{"artist": "INJECTED", "title": "Fake Song Title"}'
Expected: Should reject — user does not have the adapter API key.
Actual: Returns true. The injected artist/title appears in /api/nowplaying/1 for all…
- Record
GHSA-4fm3-ggg2-c6qx- CVSS 3.1
- 6.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-m6mg-63cr-44jj
5.3
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint...
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
- Record
GHSA-m6mg-63cr-44jj- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 6.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
NVD
5.3
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
- Record
CVE-2026-100854- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 6.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
OSV
5.3
AzuraCast before 0.23.6 Metadata Injection via Liquidsoap API
AzuraCast before 0.23.6 lacks RequireInternalConnection middleware on the Liquidsoap API endpoint and incorrectly derives the AutoDJ flag from header presence rather than validated value. Users with View station permission can inject arbitrary now-playing metadata, disrupt live broadcasts, and disclose filesystem paths.
- Record
CVE-2026-100854- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-862
- Updated
- 2026-11-02
OSVGHSA-4fm3-ggg2-c6qx
6.3
AzuraCast's Missing RequireInternalConnection on Liquidsoap API Allows Low-Privilege Metadata Injection and Broadcast Disruption
Summary
The /api/internal/{station_id}/liquidsoap/{action} endpoint is accessible from the public web interface because it lacks the RequireInternalConnection middleware that protects other internal endpoints (/sftp-auth, /sftp-event). Combined with a logic flaw where the $asAutoDj flag is set based on the presence of the X-Liquidsoap-Api-Key header rather than its validated value, any user with the basic View station permission can invoke privileged Liquidsoap commands — injecting arbitrary now-playing metadata visible to all listeners, disrupting live broadcast tracking, and disclosing absolute filesystem paths.
Details
Issue 1: Missing RequireInternalConnection middleware
In backend/config/routes/api_internal.php, the liquidsoap route group (lines 17-21) lacks the RequireInternalConnection middleware:
// Lines 17-21 — NO RequireInternalConnection
$group->map(
['GET', 'POST'],
'/liquidsoap/{action}',
Controller\Api\Internal\LiquidsoapAction::class
)->setName('api:internal:liquidsoap');
Compare with sftp endpoints that correctly apply it:
// Lines 32-34 — HAS RequireInternalConnection
$group->post('/sftp-auth', Controller\Api\Internal\SftpAuthAction::class)
->setName('api:internal:sftp-auth')
->add(Middleware\RequireInternalConnection::class);
The nginx config (util/docker/web/nginx/azuracast.conf.tmpl) only sets the IS_INTERNAL FastCGI parameter on the internal port 6010 listener (line 44), not on the public-facing server block (ports 80/443). Without the middleware, the endpoint is fully accessible from the public internet.
Issue 2: $asAutoDj derived from header presence, not validated value
In backend/src/Controller/Api/Internal/LiquidsoapAction.php:
// Line 34 — checks header PRESENCE, not value
$asAutoDj = $request->hasHeader('X-Liquidsoap-Api-Key');
// Lines 38-44 — key value only checked when ACL FAILS
$acl = $request->getAcl();
if (!$acl->isAllowed(StationPermissions::View, $station->id)) {
$authKey = $request->getHeaderLine('X-Liquidsoap-Api-Key');
if (!$station->validateAdapterApiKey($authKey)) {
throw new RuntimeException('Invalid API key.');
}
}
When a user authenticates via session/API key and has StationPermissions::View, the ACL check passes and the adapter API key is never validated. But $asAutoDj is already true from line 34 because the header is present (with any arbitrary value).
Affected commands:
FeedbackCommand(backend/src/Radio/Backend/Liquidsoap/Command/FeedbackCommand.php:36): Guardif (!$asAutoDj) return false;bypassed — creates SongHistory records and forces NowPlaying cache updatesDjOffCommand(backend/src/Radio/Backend/Liquidsoap/Command/DjOffCommand.php:24): Guard bypassed — calls$this->streamerRepo->onDisconnect($station)which ends all active broadcasts and sets$station->is_streamer_live = falseDjOnCommand(backend/src/Radio/Backend/Liquidsoap/Command/DjOnCommand.php:31): Guard bypassed — calls$this->streamerRepo->onConnect($station, $user)with attacker-controlled usernameCopyCommand(backend/src/Radio/Backend/Liquidsoap/Command/CopyCommand.php:18): No$asAutoDjguard at all — returns absolute filesystem paths via$mediaFs->getLocalPath($uri)
PoC
Prerequisites: A user account with StationPermissions::View on station ID 1 (the lowest station-level permission). Obtain a session cookie or API key for this user.
1. Inject arbitrary now-playing metadata (FeedbackCommand):
curl -X POST 'https://target/api/internal/1/liquidsoap/feedback' \
-H 'X-API-Key: <view-user-api-key>' \
-H 'X-Liquidsoap-Api-Key: anything' \
-H 'Content-Type: application/json' \
-d '{"artist": "INJECTED", "title": "Fake Song Title"}'
Expected: Should reject — user does not have the adapter API key.
Actual: Returns true. The injected artist/title appears in /api/nowplaying/1 for all…
- Record
GHSA-4fm3-ggg2-c6qx- CVSS 3.1
- 6.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-862
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
azuracast/azuracastPackagist |
through 0.23.5 | 0.23.6 |
azuracast/azuracastPackagist |
before 0.23.6, plus listed versions 0.10.00.10.10.10.20.10.30.10.4 Show 45 moreShow less0.110.11.10.11.20.120.12.10.12.20.12.30.12.40.13.00.14.00.14.10.15.00.15.10.15.20.16.00.16.10.17.00.17.10.17.20.17.30.17.40.17.50.17.60.17.70.18.00.18.10.18.20.18.30.18.50.19.00.19.10.19.20.19.30.19.40.19.50.19.60.19.70.20.00.20.10.20.20.20.30.20.40.21.00.22.00.22.1 |
0.23.6 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-100854 is a medium vulnerability (CVSS 5.3) in Azuracast, published May 4, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.19%, the 9th percentile. Fixed in azuracast/azuracast 0.23.6.
References
github.com/AzuraCast/AzuraCast/security/advisories/GHSA-4fm3-ggg2-c6qx
vulncheck.com/advisories/azuracast-before-0.23.6-metadata-injection-via-liquidsoap-api
github.com/AzuraCast/AzuraCast/commit/13fa7a71435629147b351d3ee151b8de6acd5c8c
github.com/advisories/GHSA-4fm3-ggg2-c6qx
nvd.nist.gov/vuln/detail/CVE-2026-100854
github.com/advisories/GHSA-m6mg-63cr-44jj
github.com/CVEProject/cvelistV5/tree/main/cves/2026/100xxx/CVE-2026-100854.json
github.com/AzuraCast/AzuraCast
Left out here: 30 versions and the rest of 2 source descriptions. The JSON record has them.