Critical CVE Response

CVE-2026-49869: A Suffix Match in Kestra's Login Filter Opened a Path to Root

Dark editorial illustration of a cracked padlock guarding a server rack, amber workflow-node lines spilling through the broken latch toward a cyan data stream.

A single unauthenticated PUT request is enough to plant a workflow inside Kestra, run it as root inside the worker container, and walk away with a reverse shell. Microsoft's security team traced exploitation back to late June. CISA put the fix on every federal agency's calendar this week with a deadline of September 5.

CISA added CVE-2026-49869, an operating-system command injection flaw in Kestra OSS rated CVSS 10.0, to the Known Exploited Vulnerabilities catalog on September 2, one of seven vulnerabilities added that day under BOD 26-04. Kestra shipped the fix in versions 1.0.45 and 1.3.21. Anyone still on an earlier build is running the exact configuration Microsoft watched get compromised.

If you do not self-host Kestra, or your instance already sits on 1.0.45, 1.3.21, or later, this one is not yours. If you run Kestra OSS to schedule ETL jobs, CI pipelines, or the growing pile of agentic AI and MLOps automation teams wire into it precisely because it is free and self-hostable, keep reading. Kestra ships Basic Auth on by default, and that default is exactly what this bug bypasses.

A suffix check where an exact match belonged

The bug lives in one line of AuthenticationFilter.java. To let unauthenticated clients read the public /api/v1/configs endpoint, the filter checks request.getPath().endsWith("/configs") rather than matching the exact path. Kestra addresses most resources by caller-chosen segments, tenant, namespace, and flow ID, so any request whose path happens to end in /configs slips past Basic Auth, including the endpoints that create flows, execute them, write key-value entries, and delete flows, dashboards, and logs.

Kestra also ships script-execution plugins, plugin-script-shell, plugin-script-python, and plugin-script-node, enabled by default. Put those two facts together and the authentication bypass stops being the interesting part; it is only the door. An attacker crafts a PUT request to a path ending in /configs, defines a flow with a shell, Python, or Node task in the body, triggers execution, and reads the output back from the run log. No credentials, no exploit chain beyond that one request and one flow. The result is remote code execution as root inside the Kestra worker container.

What Microsoft watched for two months

Microsoft's security team published its own account of the campaign in a blog post on securing AI infrastructure gateways, assessing with high confidence that a threat actor used CVE-2026-49869 for initial access beginning in late June. The actor bypassed the login filter, defined a malicious workflow using Kestra's Process runner, and triggered worker-side shell execution to open a reverse shell.

From there, telemetry showed the workflow-origin shell enumerating the Docker environment and touching the Docker socket, deploying a cryptocurrency miner, running defense-evasion file operations, and later using a curl-pipe-shell pattern to pull remote script content straight into a shell without writing anything to disk first. The output of at least one stage was encoded and written back into Kestra's own key-value store, using the orchestration tool's own storage layer as the exfiltration channel. Four things happened through one bug: shell execution through the workflow engine, container exposure through the Docker socket, host resource theft through the miner, and data collection through the workflow tasks themselves.

A second exposure the same advisory names

Kestra's own GitHub security advisory, GHSA-5vc5-wxxq-3fjx, flags a related issue in the same code path: the Pebble template engine's HttpFunction performs no URI filtering, so a flow or template that calls it can be pointed at internal services or a cloud metadata endpoint such as 169.254.169.254. Paired with the auth bypass, an attacker does not need valid credentials to make Kestra request whatever internal URL they choose, which on AWS, Azure, or GCP compute puts instance-metadata credential theft on the table alongside the RCE. Confirm your fix and your network egress rules cover this path too, not only the /configs check.

Patch, then check what already touched your instance

Upgrade to 1.0.45 if you run the 1.0.x line, or 1.3.21 if you run 1.3.x; both remediate the auth bypass. Do this before anything else this week. CISA's remediation date for federal agencies is September 5, and internet-wide scanning does not wait for a deadline.

Patching alone does not tell you whether the bug was already used against your instance. Confirm exposure and look for the indicators Microsoft published before you close this out.

# Confirm the auth-bypass endpoint responds without credentials (should be 401, not 200)
curl -s -o /dev/null -w "%{http_code}\n" http://KESTRA_HOST:8080/api/v1/executions/default/configs

# List flows and eyeball anything you did not create, especially ones named
# to end in "configs" or with generic, random-looking names
curl -s -u ADMIN_USER:ADMIN_PASS http://KESTRA_HOST:8080/api/v1/flows/default | jq '.[].id'

# On the worker host, check whether the Kestra container can reach the Docker
# socket -- most workflow tasks never need that mount
docker inspect $(docker ps -qf "ancestor=kestra/kestra") \
  --format '{{ range .Mounts }}{{ if eq .Destination "/var/run/docker.sock" }}MOUNTED: {{ .Source }}{{ end }}{{ end }}'

Check process history on the worker for cryptominer binaries and for curl commands piped directly into a shell. Review the key-value store for entries you cannot account for; the campaign Microsoft observed used it to stash encoded output. If the worker container had socket access to Docker, treat container escape as possible and audit every container on that host, not only the Kestra one.

Pull the Docker Socket Off Every Worker That Does Not Need It

Patch to 1.0.45 or 1.3.21 today, and while you are in the configuration, ask why the Kestra worker had a path to the Docker socket in the first place. Most workflow tasks never touch it, and the campaign Microsoft documented turned that one mount into container discovery, a cryptominer, and a persistence foothold on top of a bug that was already unauthenticated. Remove the mount everywhere it is not explicitly required. Then, if a future filter bug slips past login the way this one did, the blast radius stops at the workflow engine instead of the host underneath it.

Not sure what your automation stack can reach?

We assess CI/CD systems, workflow orchestrators, and internal automation tooling for the unauthenticated paths and excess container access attackers look for first. Book a session to review your stack.