Back to blog

CVE-2026-20245: how a tenant-list CSV upload turned Cisco SD-WAN Manager into a root shell

· · 16 min read
CVE-2026-20245: how a tenant-list CSV upload turned Cisco SD-WAN Manager into a root shell

On June 5, 2026, Cisco published an advisory for a vulnerability that was already being used in the wild: a flaw in the command-line interface of Cisco Catalyst SD-WAN Manager that lets an authenticated user with netadmin rights upload a crafted file and execute arbitrary commands as root. The bug is tracked as CVE-2026-20245 and carries a CVSS score of 7.8 (HIGH). The detail that should make every network team sit up is the one in the advisory's own footnote: at disclosure there was no patch and no workaround, only indicators of compromise. This is the seventh Cisco SD-WAN zero-day flagged as actively exploited in 2026.

What follows is a two-layered breakdown. The first part is for readers who need to decide quickly whether they have exposure and what to do about it tonight, with no assumed knowledge of the SD-WAN internals. The second part reconstructs the bug the way the Mandiant team that reported it would have: the privileged script behind a routine upload feature, the unvalidated path argument, and the short hop from "manage tenants" to "run anything as root." We close by looking at how the Pragma Core platform addresses exactly the class of problem that made this possible: a trust boundary that lived inside a shell script nobody was looking at.


Part I. Executive breakdown

What happened

Cisco Catalyst SD-WAN Manager (the product many engineers still call vManage) is the brain of a Cisco SD-WAN fabric. It is the single console from which an operator pushes configuration to every edge router, controller, and branch device in the network. If you can give instructions to the Manager, you can reshape the entire WAN.

The Manager exposes a command-line interface to administrators. One of the things that interface does is let a tenant administrator upload a list of tenants as a file, a perfectly ordinary management task. The problem is that when the Manager handed that upload off to a privileged helper script running as root, it did not properly check the file path the user supplied. An attacker who can reach that command, and who already holds netadmin privileges, can smuggle shell instructions into that path. The script runs them as root. The everyday version of the analogy: you are allowed to hand the building's facilities crew a list of names on a clipboard, and it turns out the crew will run whatever is written in the margin of the clipboard, as the building superintendent, no questions asked.

The concrete result is full root command execution on the box that controls the whole fabric. In the cases Cisco observed, attackers used that position to push configuration changes down to the edge devices the Manager controls. That is not a contained compromise of one server. That is leverage over the network itself.

Who is affected

Component Status
Catalyst SD-WAN Manager, On-Prem deployment Vulnerable. No patch at disclosure. Apply IoC hunting and hardening now.
Catalyst SD-WAN Manager, Cloud-Pro Vulnerable. Coordinate with Cisco on hosted remediation.
Catalyst SD-WAN Manager, Cloud (Cisco Managed) Vulnerable. Cisco-operated; confirm provider mitigation status.
Catalyst SD-WAN Manager, Government (FedRAMP) Vulnerable. Vulnerable across all listed environments.
Cisco SD-WAN edge routers / controllers (cEdge, vSmart) Not directly vulnerable to this CVE, but downstream targets once the Manager is compromised

The number that matters: zero. As in zero patched releases existed when this went public, and zero workarounds were offered. Cisco's only mechanical guidance was to keep current on the separate fix for CVE-2026-20182, an authentication-bypass bug (CVSS 10.0) released on May 14, 2026. That fix does not close CVE-2026-20245. It only removes one of the ways an attacker reaches the privilege level this bug requires. Active exploitation was already confirmed, including configuration pushes to managed edge devices.

Why this matters beyond Cisco

The headline is "Cisco SD-WAN," but the pattern is universal. Almost every management platform, whether it manages networks, containers, virtual machines, or CI runners, has a layer where a friendly web or CLI action gets translated into a privileged system command. That translation layer is frequently a shell script or a thin wrapper that was written to "just work," long before anyone modeled it as a security boundary. The moment a user-controlled string reaches that script without strict validation, the management plane becomes an arbitrary-code-execution plane.

This is the class of bug that scanners tuned for web injection routinely miss, because the dangerous sink is not a SQL query or an HTML template. It is a root-owned helper invoked with a path argument, three function calls away from the request handler. The bug is in the relationship between a privileged script and the input it trusts, not in any single line you can grep for.

Recommended actions

  1. There is no version to upgrade to for this CVE yet. Track Cisco's advisory (cisco-sa-sdwan) for the fixed release and apply it the moment it ships. Treat that watch as a standing task, not a one-time check.
  2. Apply the CVE-2026-20182 fix (released May 14, 2026) if you have not. It does not patch this bug, but it removes a CVSS 10.0 authentication bypass that is one of the cleanest paths to the netadmin access this exploit needs.
  3. Hunt now. Inspect /var/log/scripts.log on every Manager instance for tenant-list upload entries that reference unexpected file paths, CSV files in user home directories, or shell metacharacters. Cisco published this as the primary indicator of compromise.
  4. Audit netadmin accounts and credential hygiene. This exploit needs netadmin. Rotate credentials, enforce MFA on management access, and review who and what holds that role, including service accounts.
  5. Restrict reachability of the Manager's management interface. It should never be exposed to the internet or to general user VLANs. Constrain it to a hardened management network with explicit allow-lists.
  6. Assume-breach review of edge configuration. Because observed exploitation pushed config to edge devices, diff current edge configs against your known-good baseline and look for unauthorized policy, route, or access changes.

Part II. Technical breakdown

Background: the management plane is a privileged interpreter

Cisco Catalyst SD-WAN separates the network into planes. The data plane is the edge routers (cEdge) forwarding traffic. The control plane is the vSmart controllers distributing policy. The management plane is SD-WAN Manager, the orchestration server formerly named vManage. The Manager is where humans and automation define intent: which sites exist, which tenants exist in a multi-tenant deployment, what policy each VPN gets. The Manager then compiles that intent into device configuration and ships it down.

To do that compilation, the Manager runs a constellation of backend daemons and helper scripts under privileged accounts. vconfd (the configuration daemon) and its associated shell helpers are part of how high-level operations become concrete file and system actions. Many of those helpers run as root because they touch system paths, restart services, or write into protected directories. That is the design invariant the bug violates: those root-owned helpers are supposed to be reachable only through tightly constrained, well-validated operations. A tenant-list upload is supposed to move a CSV into a known location and parse it, nothing more.

The vulnerability: an unvalidated path argument to a root-owned helper

The flaw, in Cisco's words, is "insufficient validation of user-supplied input" in the CLI of SD-WAN Manager. The concrete shape of it is visible in the indicator of compromise Cisco published, an entry from /var/log/scripts.log on a compromised system:

Apr 15 09:44:57 vmanage vScript: Tenant list upload per vsmart serial
number: /usr/bin/vconfd_script_upload_tenant_list.sh -cli path
/home/admin/malicious.csv vpn 0

Read that line carefully, because it is the whole bug in miniature. A CLI-driven "tenant list upload" operation invokes a root-owned helper, /usr/bin/vconfd_script_upload_tenant_list.sh, and passes it user-influenced arguments: a path to the uploaded file (/home/admin/malicious.csv), a vpn identifier, and so on. The helper is the trusted, privileged component. The path is the untrusted, attacker-influenced component. The vulnerability is that the helper consumes that path without the strict validation a root-owned script requires.

Shell wrappers of this kind tend to follow a recognizable pattern. Conceptually, the dangerous shape looks like this (reconstructed to illustrate the bug class; Cisco has not published the source):

#!/bin/bash
# vconfd_script_upload_tenant_list.sh  (runs as root)
# args: -cli  path <FILE>  vpn <ID>

FILE="$3"          # attacker-influenced path argument
VPN="$5"

# the file path flows into a privileged command unsanitized.
# if FILE contains shell metacharacters or crafted content,
# they are interpreted in a root context.
process_tenant_list $FILE vpn $VPN     # <-- no quoting, no allow-list

The failure is not exotic. It is the oldest injection pattern there is: a string that a user controls flows into a command interpreter that runs with more privilege than the user, and the interpreter is never told to treat that string as inert data. Whether the precise primitive is unquoted expansion, metacharacter interpretation in the path, or crafted file contents that the parser later executes, the outcome Cisco describes is the same: command injection that yields arbitrary execution as root.

Root cause: a privilege gradient across a trust boundary nobody guarded

The interesting part is not the missing "$FILE" quote. It is why this gap survived. The request enters at the netadmin privilege level, a legitimate administrative role. It exits at root. Between those two points sits a trust boundary, the moment a netadmin-supplied value crosses into a root-executed context. The code on the netadmin side assumed the helper would defend itself. The helper assumed the caller had already validated the path. Each side trusted the other to own the check, so neither did. That is the canonical anatomy of a privilege-escalation bug: not a single bad line, but a contract gap between two components that individually look fine.

The minimal trigger is therefore not a clever payload. It is reaching the tenant-list upload command with netadmin rights and supplying a path argument that carries the injection. Everything hard about the attack is getting to netadmin in the first place.

Exploitation: chaining to netadmin, then trading netadmin for root

CVE-2026-20245 is not, on its own, a remote-unauthenticated catastrophe. It requires netadmin privileges. In practice attackers obtain that in one of three ways, and Cisco named the first two explicitly:

pre-cond: netadmin on SD-WAN Manager, obtained via:

  (a) CVE-2026-20182  -> auth bypass, CVSS 10.0
  (b) CVE-2026-20127  -> auth bypass / unauthorized access
  (c) stolen or reused netadmin credentials

then:

  CLI: tenant-list upload
       path = /home/admin/malicious.csv  (crafted)
  --------------------------------------------------
  /usr/bin/vconfd_script_upload_tenant_list.sh  (root)
       validate(path)  ->  INSUFFICIENT
       exec via path    ->  arbitrary command as root
  --------------------------------------------------
  -> root shell on the management plane
  -> config push to managed edge devices

This is why the bug is dangerous out of proportion to its 7.8 score. The score reflects the netadmin precondition. But this is the seventh SD-WAN zero-day of 2026, and the prior six include multiple authentication bypasses. An attacker rarely has to "find" netadmin: they chain a CVSS 10.0 auth bypass like CVE-2026-20182 to step in, then use CVE-2026-20245 to convert that foothold into root on the orchestration server. From root on the Manager, the attacker inherits the Manager's defining capability, pushing configuration to every device it controls. Cisco confirmed it observed exactly that: configuration changes propagated to edge devices.

Affected versions

The advisory scopes the vulnerability to the CLI of Cisco Catalyst SD-WAN Manager across every deployment model:

At the time of disclosure Cisco had not published a fixed software release for CVE-2026-20245; the advisory states a fix will be included in a future Catalyst SD-WAN Manager release, with no interim workaround. The separate fix Cisco points customers toward, for CVE-2026-20182, shipped on May 14, 2026 and addresses a different bug. Confirm the fixed release for this specific CVE against Cisco's advisory before assuming any version is safe.

Timeline

Date Event
2026-04-15 Earliest exploitation artifact appears in observed /var/log/scripts.log (per Cisco's published IoC)
2026-05-14 Cisco ships fixes for CVE-2026-20182, an SD-WAN Manager authentication bypass (CVSS 10.0)
2026-06-05 Cisco publishes the advisory for CVE-2026-20245; confirms active exploitation; states no patch and no workaround available
2026-06-05 Mandiant researchers Chester Sng, Pete Boonyakarn, and Logeswaran Nadarajan credited with discovery and reporting

A note on the discovery methodology

This bug was reported by a Google Mandiant team during what reads as incident-driven research rather than a clean lab find. The strongest tell is the indicator of compromise itself: Cisco published a real log line from a real compromised host, dated weeks before the advisory. That is the signature of investigators who found the vulnerability by following attacker artifacts back to the mechanism, reading scripts.log, noticing a tenant-list upload pointing at a file in a home directory, and asking why a routine management action was invoking a root-owned helper with an attacker-controlled path.

The transferable lesson for defenders and AppSec teams is that the most valuable place to look for this bug class is the seam between a feature and the privileged helper that implements it. You do not always need source code to find it; the invocation logs of privileged scripts are a map of exactly where untrusted input meets root. The meta-point, without overclaiming: appliance and management-plane security is dominated by these wrapper-script trust gaps, and they are found by reasoning about who calls what with which privilege, not by scanning for bad strings.


What we should learn from CVE-2026-20245

  1. Privileged helper scripts are unguarded trust boundaries. Any root-owned shell script invoked by a higher-level service is a security boundary whether or not anyone designed it as one. Inventory every such helper, identify which arguments are user-influenced, and treat each one as an injection sink until proven inert.
  2. A privilege precondition is not a safety margin. "Requires netadmin" feels like mitigation until you count the authentication bypasses sitting one hop upstream. When a product line has multiple auth-bypass CVEs in the same year, every post-auth root bug should be modeled as effectively pre-auth via chaining.
  3. The management plane is the crown jewel, so model its blast radius first. A bug that yields root on an orchestration server is not "one server." Its severity is the capability of that server, here, pushing configuration to the entire fabric. Score impact by what the compromised component controls, not by where it sits.
  4. Input validation must be owned, not assumed. The classic contract gap is each side trusting the other to validate. Make the privileged consumer responsible for its own allow-listing and quoting, every time, regardless of what the caller "should" have done.
  5. Your logs already know where the dangerous calls are. A line in scripts.log showing a feature invoking a root helper with a user-supplied path is a finding before any exploit exists. Treat privileged-script invocation logging as an audit surface, and review what calls what as root proactively.

How Pragma Core addresses this class of problem

CVE-2026-20245 is the kind of issue that off-the-shelf tooling is structurally bad at finding. The dangerous sink is not in application code a SAST engine parses; it is a root-owned shell helper invoked across a trust boundary, with the real input validation gap spread between a CLI handler and a script three calls away. Pragma Core is built for exactly this: bugs that are about how input and privilege flow across functions, services, and process boundaries, not a single bad line you can pattern-match. The platform is built by zer0day Technologies and Expertware and connects directly to a team's repositories to run continuous scanning, research, and pentesting.

Autonomous AI agents for attack-chain investigation

The autonomous agents reason over a chain instead of stopping at a flagged line. Pointed at an SD-WAN-style management codebase, the question they are built to ask is precisely the one that unravels this bug: where does the user-supplied path argument flow, which consumer of that value runs at a higher privilege than the caller, and is the validation actually reached before the privileged invocation. That is the netadmin-to-root reasoning a scanner cannot perform, applied automatically.

Interactive call graphs with privilege overlay

Pragma Core auto-generates call graphs for any connected repository and overlays findings so teams can see where untrusted input propagates and where it crosses into a more-privileged context. The flaw here lived in the relationship between the CLI tenant-upload handler and vconfd_script_upload_tenant_list.sh, not inside either one. A call graph that draws the edge from a netadmin-reachable command to a root-executed helper makes that relationship the thing you review, instead of the thing nobody noticed.

SAST tuned for command injection across process boundaries

Generic SAST is tuned for taint flows ending in SQL or web sinks and routinely misses a path argument feeding a shell helper. Pragma Core's static analysis can be tuned to the actual pattern: a user-influenced value reaching a privileged exec/system/bash invocation without quoting or an allow-list. Reframed that way, the unsanitized path flowing into a root script becomes a high-confidence finding rather than a blind spot.

White-box pentest that reads the privileged helpers

Source-assisted pentesting with agents that actually read the wrapper scripts is what surfaces this class. A white-box engagement that enumerates every root-owned helper, maps which arguments are externally influenced, and attempts injection through each is the systematic version of what Mandiant did by hand from a single log line. It turns a lucky log find into a repeatable audit.

Human-guided AppSec investigations

The expert-led research module lets an AppSec operator drive deeper analysis of the part of the system they feel is fragile, supported by the platform's autonomous agents and the full repository context. Investigating "how does our management plane turn an admin action into a privileged system command, and where does that pipeline trust its input" is exactly the kind of focused, human-steered investigation that found CVE-2026-20245, made systematic and continuous instead of incident-driven.


Closing thoughts

CVE-2026-20245 is not, fundamentally, a bug about Cisco, or about SD-WAN, or even about shell quoting. It is a bug about a trust boundary that lived inside a helper script, where a management action crossed from an administrator's privilege into root's, and no component on either side of that line owned the check. The same boundary exists in every orchestration platform that compiles human intent into privileged system actions: Kubernetes admission controllers, hypervisor management daemons, CI/CD runners, cloud control planes. The wrapper script is always there. The only question is whether anyone has modeled it.

The difference between reading this as a Cisco news item and using it as an audit trigger comes down to AppSec maturity and code visibility: do you know which privileged helpers exist in your own systems, which arguments they trust, and who can reach them. Organizations that want to move from "we scan and report" to "we systematically investigate what is fragile" can reach Pragma Core at pragma-core.com for a demo.


Sources

Related posts
CVE-2026-74820: how an unsanitized ORDER BY clause turned ServiceNow's AI Platform into an unauthenticated database backdoor
Sep 18, 2026
CVE-2026-85978: how one path normalization mismatch turned Akana's admin console into unauthenticated remote code execution
Sep 9, 2026
CVE-2026-78174: how an unredacted session token in a diagnostic log turned a low-privileged WatchGuard Dimension admin into super admin
Sep 1, 2026

Start securing your codebase today

Connect your repositories and let AI agents handle continuous scanning, research, and triage.

Have questions? Get in touch →