CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-GHMH-JHMJ-WCMF

GHSA-GHMH-JHMJ-WCMF: Plaintext Storage of Enrollment Tokens at Rest in SQLite in nebula-mesh

Alon Barad
Alon Barad
Software Engineer

Jun 23, 2026·8 min read·2 visits

Executive Summary (TL;DR)

Plaintext enrollment tokens stored in SQLite allowed attackers with database read access to register unauthorized nodes on private VPN meshes.

The self-hosted Slack Nebula VPN control plane, nebula-mesh, stored high-privilege enrollment tokens in plaintext inside its SQLite database. This flaw allowed any adversary with read access to the database to retrieve pending tokens and enroll unauthorized hosts into the secure VPN mesh.

Vulnerability Overview

nebula-mesh serves as a self-hosted control plane designed for Slack's Nebula mesh virtual private networks (VPN). The platform manages host configurations, handles cryptographic identities, and issues node certificates from a centralized administrative dashboard. In a typical deployment, the control plane exposes an API endpoint to facilitate the provisioning and registration of new endpoints within the private mesh.

During the standard host provisioning lifecycle, an administrator creates a new host entry within the control plane interface. The system then generates a unique, single-use enrollment token represented as a UUID. A local provisioning agent running on the target machine presents this token to the control plane, which validates the credentials, registers the agent's public key, and issues a valid cryptographic node certificate.

In versions up to and including v0.3.0, nebula-mesh stored these highly sensitive enrollment tokens in plaintext format within the primary SQLite storage backend. The database schema did not implement any form of hashing or transformation prior to persisting the token strings to disk. This insecure storage mechanism created a high-risk exposure window for any active, pending enrollment token.

This design flaw is classified under CWE-312 (Cleartext Storage of Sensitive Information) and CWE-256 (Unencrypted Storage of Credentials). While other critical authentication assets within the system—such as operator API keys and TOTP recovery secrets—were historically migrated to use SHA-256 hashing at rest, enrollment tokens were left unhashed. This inconsistency left the VPN enrollment infrastructure vulnerable to unauthorized exploitation.

Root Cause Analysis

The root cause of this vulnerability lies in the lack of cryptographic transformation applied to enrollment tokens before database insertion and query execution. Specifically, the database schema defined the enrollment_tokens table with a column named token which directly held the raw UUID strings. The database interaction logic failed to separate the presentation format of the token from its stored representation.

In the pre-patch implementation found in internal/store/sqlite.go, the ConsumeToken method executed a direct equality check against the raw, user-supplied UUID string. The query structured the lookup by matching the raw token argument against the plaintext database column. This logic did not utilize any hashing function, meaning a compromised database state directly translated to a compromise of all active tokens.

This architecture fails to maintain defense-in-depth principles. If an attacker gains read-only access to the SQLite database via database backups, filesystem snapshots, server compromise, or a secondary SQL injection vulnerability, they can read the tokens directly. Because the tokens were stored in plaintext, no additional cryptographic cracking or key-derivation steps were required to utilize them.

While the system marks enrollment tokens as used after consumption, this lifecycle restriction does not eliminate the security risk. The critical window of vulnerability exists between the creation of the token by the administrator and its consumption by the legitimate agent. During this active period, the plaintext token remains stored on disk, making it vulnerable to extraction and unauthorized preemption.

Code Analysis

Analyzing the vulnerable code path in version v0.3.0 highlights the direct querying of plaintext values. In internal/store/sqlite.go, the ConsumeToken method queried the database as shown below:

// Vulnerable lookup in v0.3.0 sqlite.go
t := &models.EnrollmentToken{}
err = tx.QueryRow(
    `SELECT id, host_id, token, used, expires_at, created_at FROM enrollment_tokens WHERE token = ?`,
    token,
).Scan(&t.ID, &t.HostID, &t.Token, &t.Used, &t.ExpiresAt, &t.CreatedAt)

To resolve this issue in version v0.3.2, the developers introduced a cryptographic hashing layer. The model implementation in internal/models/token.go was updated to define a SHA-256 hashing utility. This helper function ensures that raw tokens are converted to their hex-encoded SHA-256 representation before database operations:

// Patched hashing helper in v0.3.2 models/token.go
func HashEnrollmentToken(raw string) string {
    sum := sha256.Sum256([]byte(raw))
    return hex.EncodeToString(sum[:])
}

The database lookup in internal/store/sqlite.go was subsequently modified to perform the equality check on the hashed values. The query now matches against the token_hash column using the hashed version of the incoming client token:

// Patched query execution in v0.3.2 sqlite.go
t := &models.EnrollmentToken{}
err = tx.QueryRowContext(ctx,
    `SELECT id, host_id, token_hash, used, expires_at, created_at FROM enrollment_tokens WHERE token_hash = ?`,
    models.HashEnrollmentToken(token),
).Scan(&t.ID, &t.HostID, &t.TokenHash, &t.Used, &t.ExpiresAt, &t.CreatedAt)

The patch is complete and robust because it completely eliminates plaintext token storage at rest. The migration schema script 016_enrollment_token_hash.up.sql renames the column from token to token_hash, ensuring that any direct database query returns only SHA-256 hashes. This approach guarantees that even if the database is fully compromised, an attacker cannot reverse the SHA-256 hashes to reconstruct the valid UUID tokens required for enrollment.

Exploitation Methodology

The exploitation process requires the attacker to obtain read access to the SQLite database file (nebula-mgmt.db). This read access can be achieved via server-side file disclosure, local filesystem access, compromised backup storage, or an independent SQL injection vulnerability. Once database access is established, the exploitation is straightforward and reliable.

The attacker first queries the enrollment_tokens table to locate active, unconsumed tokens. The target records are those where the used column is set to 0 and the expires_at timestamp is in the future. The query below demonstrates how an attacker would retrieve these pending tokens:

-- Attacker query to extract valid plaintext tokens from v0.3.0 database
SELECT token, host_id FROM enrollment_tokens WHERE used = 0 AND expires_at > datetime('now');

Upon extracting a valid plaintext UUID token, the attacker preempts the legitimate host registration process. The attacker sends an HTTP POST request containing the stolen token and a self-generated public key to the nebula-mesh enrollment endpoint.

# Conceptual representation of the enrollment API request
curl -X POST -d '{"token": "extracted-uuid-token", "public_key": "attacker-public-key"}' https://control-plane.example.com/api/enroll

Because the control plane validates the raw token against the database and finds a matching active record, it accepts the request. The control plane marks the token as used, binds the attacker's public key to the targeted host identity, and returns a signed cryptographic certificate. The attacker then configures their local Nebula client with this certificate, establishing an authorized endpoint inside the private VPN mesh.

Security Impact Assessment

The primary impact of this vulnerability is the complete compromise of the trusted network boundary. Nebula mesh networks are typically deployed to enforce zero-trust network segmentation. By successfully exploiting this vulnerability, an attacker bypasses all network-level access controls and gains direct entry into the private, encrypted mesh network.

The attacker inherits the identity of the host associated with the compromised enrollment token. This allows them to communicate with other nodes on the mesh network, perform lateral scanning, and exploit internal services that are otherwise shielded from the public internet. The scope of access is dictated by the network policies assigned to the compromised host identity.

Furthermore, the compromise has long-term persistence implications. Once the control plane issues a signed certificate to the attacker, that certificate remains valid until its natural expiration date unless explicitly revoked via a Certificate Revocation List (CRL). Securing the database or upgrading the software post-exploitation does not invalidate previously issued certificates.

The vulnerability is rated 5.1 (Medium Severity) under CVSS v4.0. While the impact on the private network is substantial, the score is moderated by the requirement of initial read access to the database. However, in environments with shared database servers or automated backup synchronization, the likelihood of database exposure increases, making prompt remediation critical.

Remediation and Hardening

Mitigation of this vulnerability requires upgrading the nebula-mesh installation to version v0.3.2 or newer. This upgrade automatically executes the SQL migration script 016_enrollment_token_hash.up.sql, renaming the token column to token_hash and enforcing the hashed storage model.

Administrators must be aware of the operational impact of the database migration. When the schema is migrated, existing unconsumed tokens will remain in the database as plaintext inside the renamed token_hash column. Because the patched application hashes incoming tokens using SHA-256 before searching the database, these plaintext records will fail to match, rendering existing unconsumed tokens unusable.

To resolve this operational issue, administrators must regenerate enrollment tokens for any hosts that have not completed their provisioning flow prior to the upgrade. Freshly generated tokens will be correctly processed, hashed using SHA-256, and stored securely.

If an immediate upgrade is not possible, temporary mitigations must be applied to secure the database. Administrators should restrict the filesystem permissions of the SQLite database file using chmod 0600 so that only the dedicated application service user has read and write permissions. Additionally, any automated database backup files must be encrypted at rest and restricted to authorized security personnel.

Technical Appendix

CVSS Score
5.1/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N

Affected Systems

nebula-mesh (github.com/juev/nebula-mesh)nebula-mesh (github.com/forgekeep/nebula-mesh)

Affected Versions Detail

Product
Affected Versions
Fixed Version
nebula-mesh
forgekeep
<= v0.3.0v0.3.2
AttributeDetail
CWE IDCWE-312, CWE-256
Attack VectorLocal / Read-only Database Access
CVSS v4.0 Score5.1 (Medium)
Exploit Statuspoc
ImpactUnauthorized VPN Mesh Host Enrollment
Remediation StatusPatched in v0.3.2

MITRE ATT&CK Mapping

T1552.001Unsecured Credentials: Private Keys and Tokens
Credential Access
T1133External Remote Services
Persistence
CWE-312
Cleartext Storage of Sensitive Information

The product stores sensitive information in cleartext in a system resource, such as a database, that can be read by an unauthorized actor.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory details for plaintext token vulnerability in SQLite store.

References & Sources

  • [1]GHSA-GHMH-JHMJ-WCMF Security Advisory
  • [2]SQL Migration Patch Source

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•CVE-2026-48153
8.5

CVE-2026-48153: Server-Side Request Forgery in Budibase OAuth2 SDK

CVE-2026-48153 is a Server-Side Request Forgery (SSRF) vulnerability in the Budibase OAuth2 SDK prior to version 3.39.0. It allows authenticated low-privileged users to bypass outbound network security blacklists and send arbitrary requests to internal subnets or cloud metadata services.

Alon Barad
Alon Barad
2 views•7 min read
•about 13 hours ago•GHSA-HVQH-JW65-WCPQ
6.1

GHSA-HVQH-JW65-WCPQ: Cross-Site Scripting (XSS) in devbridge-autocomplete

The devbridge-autocomplete package (jQuery-Autocomplete) fails to escape category headers and suggestion values when using default formatters formatGroup and formatResult. If suggestions contain untrusted input, arbitrary HTML and JavaScript execute directly in the victim's browser session.

Alon Barad
Alon Barad
3 views•6 min read
•about 17 hours ago•CVE-2024-37155
6.5

CVE-2024-37155: Security Bypass in OpenCTI GraphQL Introspection via Whitespace and Control Character Manipulation

OpenCTI versions prior to 6.1.9 fail to properly restrict GraphQL schema introspection queries due to a weak pattern-matching implementation. An unauthenticated attacker can bypass the introspection block list by stripping whitespace and carriage returns, enabling complete reconnaissance of the GraphQL schema.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 18 hours ago•CVE-2025-58048
10.0

CVE-2025-58048: Remote Code Execution via Unrestricted Ticket Attachment Uploads in Paymenter

An unrestricted file upload vulnerability in Paymenter's support ticket system (prior to version 1.2.11) allows authenticated users to upload arbitrary PHP scripts to a web-accessible directory. The application fails to validate file extensions or MIME types before storing the files, enabling remote code execution under the web server's privilege context.

Amit Schendel
Amit Schendel
6 views•5 min read
•about 19 hours ago•CVE-2026-21887
7.7

CVE-2026-21887: Server-Side Request Forgery in OpenCTI Data Ingestion Component

A technical analysis of CVE-2026-21887, a Server-Side Request Forgery (SSRF) vulnerability in OpenCTI. The flaw occurs in the platform's data ingestion mechanism, which processes user-supplied feed URLs via Axios under a default configuration. Authenticated users with low privileges can exploit this to pivot into internal infrastructure, target metadata services, and scan private networks.

Amit Schendel
Amit Schendel
4 views•7 min read
•1 day ago•GHSA-6GQW-JQV7-V88M
7.2

GHSA-6GQW-JQV7-V88M: Multi-Tenant Isolation Bypass in stigmem-node via Missing SQL Tenant Predicates

A critical vulnerability exists in the stigmem-node package when running the opt-in stigmem-plugin-multi-tenant plugin. Due to a failure to enforce tenant-scoping filters on database queries within the decay sweep, quarantine moderation, and right-to-be-forgotten (RTBF) subsystems, an authorized caller belonging to one tenant can access, modify, and delete facts belonging to all other tenants. This broken object level authorization (BOLA) vulnerability allows cross-tenant data manipulation and information leakage.

Amit Schendel
Amit Schendel
6 views•6 min read