Automated Threat Modeling

Windmill CVE-2026-47107: Brief Summary of Cross Tenant DNS Poisoning via nsjail Sandbox Misconfiguration

A brief summary of CVE-2026-47107, a critical incorrect default permissions flaw in Windmill's nsjail sandbox configuration. It lets authenticated users poison DNS entries and intercept credentials across tenant boundaries on shared worker pods.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-05-19

Windmill CVE-2026-47107: Brief Summary of Cross Tenant DNS Poisoning via nsjail Sandbox Misconfiguration
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A single non-recursive read-only remount in Windmill's nsjail sandbox configuration left Kubernetes-injected files writable inside script execution jails. Any authenticated user could then poison DNS resolution persistently and intercept credentials from every tenant sharing the same worker pod. CVE-2026-47107 has a CVSS score of 9.6, and exploiting it takes nothing more than the ability to run a sandboxed script. For multi-tenant Windmill deployments, that is a serious exposure.

Windmill is an open-source developer platform (AGPLv3) that provides infrastructure for internal APIs, background jobs, and workflows. Organizations use it to orchestrate automation pipelines, and it offers multiple layers of process isolation, including nsjail sandboxing, to protect infrastructure from malicious code. Multi-tenant deployments share long-lived worker pods, so any sandbox escape becomes a cross-tenant problem.

Technical Information

Root Cause: Non-Recursive Read-Only Remount

The vulnerability stems from how nsjail applies mount namespace restrictions in Kubernetes environments. Windmill's nsjail configuration files mount the entire /etc directory as read only. That works for ordinary files that exist directly on the filesystem. In Kubernetes, though, the kubelet injects specific files into /etc as separate bind mounts layered on top of the directory. These include /etc/hosts, /etc/resolv.conf, and /etc/hostname.

nsjail applies its read-only remount non-recursively, and the classic mount syscall does not propagate the read-only status to submounts. As a result, the kubelet-injected files remain fully writable inside the jail, even though the parent /etc directory is mounted read only.

Writable Targets

The table below lists the files reported as writable and which source reports each one:

File TargetConfirmed by Windmill PR #9194Cited by VulnCheck AdvisoryNotes
/etc/hostsYesYesKubelet submount remains writable
/etc/resolv.confYesYesKubelet submount remains writable
/etc/hostnameYesNoKubelet submount remains writable
/etc/ssl/certs/ca-certificates.crtNoYesCited in advisory; requires local validation

Attack Flow

Exploitation proceeds in five steps:

  1. Initial access: An authenticated user with permission to execute scripts in any Windmill workspace submits a job that runs inside the nsjail sandbox.

  2. File modification: From within the sandbox, the attacker writes malicious entries to the writable files. For example, they can append entries to /etc/hosts that redirect legitimate hostnames to attacker-controlled IP addresses, or modify /etc/resolv.conf to point DNS resolution at an attacker-controlled resolver.

  3. Persistence via pod reuse: Windmill worker pods are long-lived and reused across all workspaces and tenants. The poisoned entries persist at the pod level for the lifetime of the worker pod, and every later job executed on that pod inherits the poisoned configuration.

  4. Cross-tenant impact: When a victim in a different tenant runs a script on the same worker pod, their job's network traffic follows the attacker's DNS and host redirections. From there the attacker can:

    • Redirect hostnames to attacker-controlled servers via /etc/hosts
    • Intercept all DNS queries via a rogue resolver in /etc/resolv.conf
    • Perform transparent HTTPS man-in-the-middle attacks by injecting a rogue CA certificate, if /etc/ssl/certs/ca-certificates.crt is also writable
    • Intercept WM_TOKEN JWTs, which grant workspace admin access to victim workspaces
  5. Credential theft and lateral movement: With the intercepted WM_TOKEN JWTs, the attacker gains workspace admin privileges in victim workspaces across tenant boundaries. From there they can exfiltrate more data or mount supply chain attacks by redirecting package registry traffic.

Why This Is Particularly Dangerous

Three factors combine here. The attack needs only low privilege (any authenticated user who can run a script), persistence is automatic because worker pods are reused, and the blast radius covers every tenant on the affected worker. The victim also gets no sign that their DNS resolution has been tampered with.

The Fix in Version 1.703.2

The patch in Pull Request #9194 adds explicit read-only per-file binds for the affected files to all eighteen nsjail configuration files. Each bind shadows a writable kubelet submount with a read-only view of the same content, which closes the gap the non-recursive remount left open.

The fix applies only to the nsjail isolation mode. The "unshare" and "none" isolation modes do not use mount namespaces, and the patch does not cover them:

Isolation ModeMount Namespace PresentCovered by 1.703.2 FixRecommendation
nsjailYesYesEnforce for all multi-tenant workloads
unshareNoNoAvoid for multi-tenant environments
noneNoNoAvoid for multi-tenant environments

Affected Systems and Versions

All Windmill versions before 1.703.2 are affected when they use the nsjail isolation mode in Kubernetes deployments. The vulnerability requires:

  • Windmill versions before 1.703.2
  • nsjail isolation mode enabled
  • Deployment on Kubernetes (where the kubelet injects bind mounts into /etc)
  • Multi-tenant configuration with shared worker pods

Single-tenant deployments, and deployments not running on Kubernetes, may not be affected by the kubelet submount behavior. Validate this independently for your own environment.

Vendor Security History

Windmill has had several notable security issues recently:

IssueIdentifierImpact
Path traversal in log endpointGHSA-24fr-44f8-fqwgExposure of SUPERADMIN_SECRET leading to potential code execution
Slack OAuth secret disclosureCVE-2026-26964Exposure of sensitive OAuth tokens to non-admin users
nsjail submount writabilityCVE-2026-47107Cross-tenant DNS poisoning and token theft

These issues cluster around access control and isolation boundaries, which organizations that depend on Windmill in security-sensitive contexts should keep in mind. The maintainers have been responsive in addressing reported issues, but the recurrence suggests that isolation and permission boundaries need a more systematic review.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization