On October 22, 2026, Arista warned that a critical SQL injection flaw in VeloCloud Orchestrator (VCO), the central management system for VeloCloud SD-WAN, had been exploited in the wild as a zero-day. The worrying part is who could use it: anyone with a valid login, including a read-only customer account. The Hacker News reported the details.
It's a clean example of a pattern that shows up in ordinary web apps too: an authenticated injection bug that turns the lowest role into the highest one.
What happened
According to the report, the flaw is tracked as CVE-2026-114625 and rated CVSS 9.9. It is a SQL injection in the orchestrator's web interface. To exploit it, an attacker needs a valid login and network access to the web UI, and the minimum role required is Enterprise Read Only.
In the report's words, "the flaw lets anyone who can log in to the orchestrator, even with a read-only customer account, gain operator privileges." From there an attacker can act as the local superuser, which may affect the VCO host itself and expose, modify or disrupt data.
Some details matter for defenders:
- The vulnerable parameter has not been disclosed. We don't know which request or field carries the injection, and we won't guess.
- "VCO is exposed by default", per the report, so the web interface may be reachable from more places than intended.
- Fixed versions are 5.2.3.18 and later, 6.1.3.10 and later, and 6.4.2.12 and later. Hosted and dedicated deployments were already patched. VeloCloud Gateway and Edge are not affected.
- Earlier fixes are not enough. Releases that fixed the July (CVE-2026-16812) and September (CVE-2026-93952) flaws are still vulnerable to this one.
- Indicators of compromise listed in the report are 74.82.197[.]86 and 38.54.50[.]151.
Arista's mitigations are to restrict the web interface to trusted admin networks, watch for unexpected outbound traffic, and review admin activity.
Why it worked
The root cause in VCO is not public beyond "SQL injection", so this section is about the class, not Arista's code.
Most web apps enforce roles in the application layer: a decorator or middleware checks "is this user allowed to call this endpoint?" and then the handler runs a query. That works only as long as the query does exactly what the handler intended. If any value from the request is pasted into the SQL text, the user stops supplying data and starts writing part of the query. At that point the role check has already passed, and the database will happily run whatever the attacker wrote with the application's own database privileges.
Here is an illustrative example, not the product's code. A read-only report endpoint builds its filter with string formatting:
# Vulnerable: the "site" value becomes part of the SQL text
@require_role("read_only")
def list_events(request):
site = request.args["site"]
sql = f"SELECT id, kind, ts FROM events WHERE site = '{site}'"
return db.execute(sql).fetchall()A value like x'; UPDATE users SET role = 'operator' WHERE name = 'me'; -- (where the driver allows stacked statements) changes the role table instead of filtering events. Even without stacked statements, UNION SELECT can read tables the role was never meant to see. The fix is to keep data and code separate:
# Fixed: the driver sends "site" as a bound parameter, never as SQL
@require_role("read_only")
def list_events(request):
site = request.args["site"]
sql = "SELECT id, kind, ts FROM events WHERE site = %s"
return db.execute(sql, (site,)).fetchall()Parameterised queries are the primary defence. Validating input shape (an id is an integer, a site name matches an allowlist) is a useful second layer, but it isn't a substitute.
Least privilege belongs in the database too
The second lesson is about blast radius. If the application connects to the database with one powerful account for every request, an injection in a read-only screen inherits the power to write anything. Where it is practical, give read paths a database role that can only SELECT the tables they need, and keep schema changes and user administration on a separate account. An injection is still a bug, but it no longer turns "read-only" into "operator". Our post on broken access control covers the application-layer half of the same problem.
What to do now
If you run VeloCloud Orchestrator:
- Upgrade to 5.2.3.18, 6.1.3.10 or 6.4.2.12 (or later) for your release line. Don't assume an earlier 2026 patch covers this flaw; per the report it doesn't.
- Restrict the web interface to trusted admin networks. Since the report says VCO is exposed by default, check what is actually reachable from the internet.
- Review admin activity for unexpected role changes or operator actions taken by read-only accounts.
- Watch for unexpected outbound traffic from the VCO host, and check logs for the two IPs listed above.
- Audit which accounts exist at all. Every valid login, including read-only customer accounts, was enough to exploit this.
For your own applications, the same class of bug is worth a sweep:
- Search for SQL built with f-strings,
+concatenation,%formatting or template literals, and replace each with bound parameters. - Treat ORM "raw" escape hatches (
raw(),text(),$queryRawUnsafeand similar) as places that need review. - Split database accounts so read-only features run with read-only credentials.
- Add a test that sends a quote and a
UNIONpayload to each filter parameter and expects a normal error, not a different result set.
How OpenRouting helps
OpenRouting looks for this class of bug in the code you connect, not in vendor products:
- Semgrep rules flag SQL assembled from request data across Python, JavaScript/TypeScript, Java, Go, Ruby, PHP, C# and other languages, including raw-query calls in common ORMs.
- The SQL injection agent reviews each SQL finding with the surrounding code, decides whether the value is really attacker-controlled, and explains the fix in plain English with a suggested patch. This AI triage runs on Claude, via Amazon Bedrock, and secret values are redacted before any AI call.
- The access control agent reviews role and permission findings, the "who may call this" half of the story.
- PR review scans the changed files of a pull request, so a new string-built query can be caught before it merges.
What it won't catch
- OpenRouting scans your repositories and, passively, your websites. It does not scan Arista's product or any other vendor appliance, and it can't tell you which VCO version you run.
- It does not do dependency or SCA scanning yet, so it won't warn you that a library or appliance version is vulnerable. Use the vendor advisory and your patching process for that.
- A database account that is too powerful is a deployment setting; a code scan only sees it if the credentials or grants live in the repository.
- Findings come from a scan you run, manually or as a PR review. Nothing is checked until a scan runs.