Skip to main content
Vulnerability Database/CVE-2026-19624

CVE-2026-19624: NetworkManager-l2tp Privilege Escalation

CVE-2026-19624 is a privilege escalation flaw in NetworkManager-l2tp allowing local unprivileged users to execute commands as root through malicious VPN profiles. This article covers technical details, impact, and mitigation.

Published:

CVE-2026-19624 Overview

CVE-2026-19624 is an argument injection vulnerability [CWE-88] in NetworkManager-l2tp, the Layer 2 Tunneling Protocol (L2TP) VPN plugin for NetworkManager on Linux. The plugin writes attacker-controlled VPN connection properties into a generated ipsec.conf file without escaping newline or control characters. The pluto IKE daemon then loads this configuration and executes directives as root. A local unprivileged user can craft an L2TP VPN profile containing an injected leftupdown directive that runs arbitrary commands as root when the IKE security association is established. This bug class mirrors CVE-2018-10900 in NetworkManager-vpnc.

Critical Impact

Any local unprivileged user who can create and activate a VPN profile via NetworkManager can escalate to root through a newline-injected leftupdown command executed by pluto.

Affected Products

  • NetworkManager-l2tp (upstream project maintained at nm-l2tp/NetworkManager-l2tp)
  • Linux distributions packaging vulnerable NetworkManager-l2tp releases, including Fedora (Fedora Bodhi tracker)
  • Systems using either Libreswan (pluto) or strongSwan (charon) as the IPsec backend

Discovery Timeline

  • 2026-09-14 - CVE-2026-19624 published to the National Vulnerability Database
  • 2026-09-18 - Last updated in NVD database

Technical Details for CVE-2026-19624

Vulnerability Analysis

NetworkManager-l2tp translates user-supplied VPN connection properties (vpn.data and vpn.secrets) into an ipsec.conf file consumed by the IPsec daemon. The plugin performs no sanitization of control characters when writing these values. Because ipsec.conf is a line-oriented configuration format, a newline embedded in a property value terminates the current directive and begins a new one. An attacker can inject an arbitrary configuration keyword, including leftupdown, which specifies a shell command that pluto executes as root at defined tunnel lifecycle events.

Activation of the malicious profile causes pluto to invoke the injected command with root privileges, yielding local privilege escalation. The write path runs under the NetworkManager service, but the executed payload runs in the IPsec daemon context. The issue is the same argument injection pattern documented in CVE-2018-10900 for NetworkManager-vpnc.

Root Cause

The root cause is missing input validation on VPN property values before they are serialized into ipsec.conf. The plugin used getenv() and property values directly in write_config_option() format strings without rejecting control characters, allowing newline-based directive injection. See the Linneman Labs analysis for a detailed walkthrough.

Attack Vector

Exploitation requires local access with the ability to create and activate a NetworkManager VPN connection, a capability granted to unprivileged desktop users on most Linux distributions. The attacker constructs an L2TP profile in which a property value contains \n leftupdown="<command>" and activates it. When the IKE SA is established, pluto executes the command as root.

c
// Patch: src/nm-l2tp-service.c introduces string_contains_control_char()
// and rejects control characters in PLUTODEBUG and CHARONDEBUG env vars.
static gboolean
string_contains_control_char(const char *value)
{
    if (!value)
        return FALSE;

    for (const char *p = value; *p; p++) {
        if (g_ascii_iscntrl(*p))
            return TRUE;
    }

    return FALSE;
}

static void
validate_one_property(const char *key, const char *value, gpointer user_data)
{
    /* property validation now rejects control characters */
}

Source: GitHub Commit 95b6b46

c
// Environment variable hardening in the IPsec config writer
const char *plutodebug = getenv("PLUTODEBUG");

if (plutodebug && !string_contains_control_char(plutodebug)) {
    write_config_option(fd, "  plutodebug=\"%s\"\n\n", plutodebug);
} else if (plutodebug) {
    _LOGW("Ignoring PLUTODEBUG environment variable because it contains a control character");
}

Source: GitHub Commit 3704d8c

Detection Methods for CVE-2026-19624

Indicators of Compromise

  • Generated ipsec.conf files under /var/run/nm-l2tp-* or /tmp containing a leftupdown= directive that references a shell command, script path, or interpreter not shipped by the distribution.
  • Child processes of pluto or charon executing shells (/bin/sh, /bin/bash) or writing to sensitive paths such as /etc/passwd, /etc/shadow, or /root/.ssh/authorized_keys.
  • NetworkManager D-Bus AddConnection or Update calls from unprivileged users containing embedded newline (\n, 0x0A) or carriage return (0x0D) bytes in vpn.data or vpn.secrets values.

Detection Strategies

  • Monitor process ancestry for pluto or charon spawning any non-standard binary during IKE negotiation.
  • Audit VPN connection files under /etc/NetworkManager/system-connections/ for unusual vpn.data values containing embedded control characters.
  • Alert on any execve where the parent is pluto and the argument vector references world-writable directories.

Monitoring Recommendations

  • Enable auditd rules on /etc/NetworkManager/system-connections/ and NetworkManager D-Bus method calls to correlate VPN profile changes with subsequent privileged process execution.
  • Baseline expected leftupdown values in your environment; the default is empty or the distribution-supplied _updown script.
  • Correlate NetworkManager service logs with pluto/charon logs to identify IKE SA establishment events triggered by non-admin users.

How to Mitigate CVE-2026-19624

Immediate Actions Required

Patch Information

Upstream fixes are provided by commits 3704d8c and 95b6b46. These patches add the string_contains_control_char() helper and reject VPN property values and IPsec debug environment variables that contain ASCII control characters, preventing newline-based directive injection into ipsec.conf.

Workarounds

  • Remove the NetworkManager-l2tp package on systems that do not require L2TP VPN connectivity.
  • Restrict who can create and activate NetworkManager VPN connections by tightening the polkit rule org.freedesktop.NetworkManager.settings.modify.system to admin users only.
  • Disable the L2TP plugin at startup and require administrator-created profiles until the patched package is deployed.
bash
# Restrict VPN connection modification to wheel/admin group via polkit
cat >/etc/polkit-1/rules.d/10-nm-l2tp-restrict.rules <<'EOF'
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.NetworkManager.settings.modify.system" ||
        action.id == "org.freedesktop.NetworkManager.settings.modify.own") {
        if (!subject.isInGroup("wheel")) {
            return polkit.Result.NO;
        }
    }
});
EOF

# Verify installed package version
rpm -q NetworkManager-l2tp || dpkg -l | grep network-manager-l2tp

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.