Safeguard
Application Security•

Kestra CVE-2026-49869: A Suffix Match That Gave Away Root RCE

Kestra OSS skipped Basic Auth for any API path ending in /configs, which let anyone create and run a workflow as root. CISA added it to KEV on 2 September 2026.

Safeguard Security Team
5 min read

On 2 September 2026 CISA added CVE-2026-49869, an authentication bypass in the Kestra OSS orchestration platform, to its Known Exploited Vulnerabilities catalog. The federal due date was 5 September. The bug was disclosed in June with a CVSS 3.1 score of 10.0, and fixes have been out since then.

The root cause fits in one line of Java. Kestra's AuthenticationFilter whitelisted its public config endpoint with request.getPath().endsWith("/configs"). Any API route whose last segment is configs skipped authentication, and an attacker can create a flow with that name.

What's affected

  • Product: Kestra OSS, the open source orchestration platform.
  • Vulnerable: versions up to and including 1.3.20, except 1.0.45 and later 1.0.x releases. The advisory was tested against 1.3.20.
  • Fixed: 1.0.45 and 1.3.21.
  • Condition: Basic Auth mode, which the advisory says is the default authentication mode for Kestra OSS. The instance does not need to be internet facing. Network access to the API port is enough.

Advisory GHSA-5vc5-wxxq-3fjx, credited to Vasco0x4, walks through the chain. The filter meant to expose only GET /api/v1/configs and the tenant equivalent. Because of the suffix match, these also bypassed auth (shown with the tenant main and namespace tutorial used in the advisory's proof of concept):

  • PUT /api/v1/main/flows/tutorial/configs creates or overwrites a flow named configs.
  • POST /api/v1/main/executions/tutorial/configs runs it.
  • PUT /api/v1/main/namespaces/tutorial/kv/configs writes a KV entry.
  • DELETE /api/v1/main/logs/tutorial/configs wipes execution logs for that flow.

Kestra ships script plugins such as io.kestra.plugin.scripts.shell.Commands and io.kestra.plugin.scripts.python.Script by default. So an attacker creates a flow called configs with a shell task, executes it, and gets commands running as uid=0 inside the worker container. The advisory also notes the Pebble http() function has no URI filtering, so the same foothold can reach 169.254.169.254 and steal cloud instance credentials.

How to check if you're exposed

Find the running version. For Docker deployments:

docker ps --format '{{.Image}}' | grep -i kestra
docker inspect --format '{{.Config.Image}}' kestra

For Kubernetes:

kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | grep -i kestra

The GitHub advisory marks every version up to 1.3.20 as vulnerable, with 1.0.45 as the fix for the 1.0 line. So 1.0.x needs 1.0.45 or later, and anything newer than the 1.0 line needs 1.3.21 or later.

Then look for signs of use. A flow whose id is literally configs is the clearest indicator, since the exploit needs one. Search your flows in the UI for that id in every namespace, and check reverse proxy or ingress logs for write methods on paths that end in /configs:

grep -E '"(PUT|POST|DELETE) /api/v1/[^ "]*/configs' /var/log/nginx/access.log*

A legitimate client only ever sends GET to the config endpoint. Any PUT, POST or DELETE ending in /configs is worth a closer look. Because the attacker can delete the matching execution logs, proxy logs held outside Kestra matter more than Kestra's own.

What to do now

  1. Upgrade to 1.3.21 or 1.0.45 or later.
  2. Until then, block every non GET request whose path ends in /configs at your reverse proxy, and restrict network access to the Kestra API to the hosts that need it.
  3. Delete any flow named configs you didn't create, and export it first for investigation.
  4. If you find evidence of use, assume the worker container ran attacker code as root. Rotate every secret and KV value the instance holds, and on cloud hosts rotate the instance role credentials, since the advisory shows metadata endpoints were reachable.
  5. Review which script plugins you actually need. Removing unused ones shrinks what a future auth bug can do.

Why it matters

Workflow orchestrators are built to run arbitrary code. That is their job. So any authentication gap in front of one is a remote code execution bug by design, and the worker usually holds credentials for databases, cloud accounts and data pipelines.

The coding lesson is simple and repeats across frameworks: never allowlist routes with prefix or suffix string matching on a path you don't fully control. Match the exact route, or attach the "public" decision to the route definition itself.

Try it yourself

Search your own codebase for path based auth exceptions. In Java and Kotlin services, a quick start is:

grep -rnE 'getPath\(\)\.(endsWith|startsWith|contains)\(' --include=*.java --include=*.kt .

For each hit, ask whether an attacker could name a resource so the check matches. This demo shows how a static code scan surfaces patterns like this one:

Click through it at your own pace, or open it full screen.

Quick check

Does the Kestra instance have to be exposed to the internet?

No. The advisory says any attacker with network access to the API port can exploit it, so internal instances are at risk from anyone already inside the network.

Why does the bypass only apply to resources named configs, and why doesn't that limit it?

The filter skipped auth for paths ending in /configs. The attacker can create a flow with the id configs without authenticating, then execute it, so the naming constraint doesn't stop the attack.

Which versions fix CVE-2026-49869?

Kestra 1.0.45 and 1.3.21.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.