Every CVE Search/ Get API key

CVE-2026-55098

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

6.5 MediumFix available

Arc is an open, SQL-native time-series database for telemetry. Prior to the repository-verified 26.06.2 repair, the remediation of CVE-2026-47735 leaves a cross-database authorization bypass through DuckDB table-valued I/O functions. In internal/database/sandbox.go, allowed_directories uses cfg.LocalStorageRoot, configured by storage.local_path, while enable_external_access=false blocks access outside that entire multi-tenant root. GetStoragePath in internal/storage/util.go stores all databases beneath it. In internal/api/query.go, extractTableReferences skips names followed by an opening parenthesis and checkQueryPermissions allows queries with no extracted table references, including tokens with permissions: []. The userSQLReadParquetPattern denylist catches literal read_parquet( and the earlier protection also blocks arc_partition_agg(, but misses the parquet_scan alias and glob, parquet_metadata, parquet_schema, read_blob, read_csv_auto, read_json and read_text. A request to POST /api/v1/query using these unblocked functions passes ValidateSQLRequest and convertSQLToStoragePaths without tenant authorization, allowing reads and enumeration of other databases' time-series data, schema and per-column value-range statistics within the allowlisted root. The sandbox still blocks out-of-root OS files and HTTP SSRF, and the sibling SQLite token database outside the root is not exposed by this mechanism. The earlier 26.06.1 remediation does not comprehensively deny these I/O functions. Repository tag 26.06.2 contains the I/O-function repair and supplies the provisional remediation boundary; conflicting advisory affected-version statements require curator adjudication.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.32%Unchanged since Oct 31, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.5

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

Arc is an open, SQL-native time-series database for telemetry. Prior to the repository-verified 26.06.2 repair, the remediation of CVE-2026-47735 leaves a cross-database authorization bypass through DuckDB table-valued I/O functions. In internal/database/sandbox.go, allowed_directories uses cfg.LocalStorageRoot, configured by storage.local_path, while enable_external_access=false blocks access outside that entire multi-tenant root. GetStoragePath in internal/storage/util.go stores all databases beneath it. In internal/api/query.go, extractTableReferences skips names followed by an opening parenthesis and checkQueryPermissions allows queries with no extracted table references, including tokens with permissions: []. The userSQLReadParquetPattern denylist catches literal read_parquet( and the earlier protection also blocks arc_partition_agg(, but misses the parquet_scan alias and glob, parquet_metadata, parquet_schema, read_blob, read_csv_auto, read_json and read_text. A request to POST /api/v1/query using these unblocked functions passes ValidateSQLRequest and convertSQLToStoragePaths without tenant authorization, allowing reads and enumeration of other databases' time-series data, schema and per-column value-range statistics within the allowlisted root. The sandbox still blocks out-of-root OS files and HTTP SSRF, and the sibling SQLite token database outside the root is not exposed by this mechanism. The earlier 26.06.1 remediation does not comprehensively deny these I/O functions. Repository tag 26.06.2 contains the I/O-function repair and supplies the provisional remediation boundary; conflicting advisory affected-version statements require curator adjudication.

Record
CVE-2026-55098
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-200, CWE-863
Updated
2026-11-02
EUVDEUVD-2026-114443 6.5

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

Record
EUVD-2026-114443
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Updated
2026-11-04
GitHub AdvisoriesGHSA-93cm-2v4m-c56c 6.5

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

Summary

The fix for CVE-2026-47735 (released 2026.06.1) is incomplete. It added a DuckDB sandbox (SET GLOBAL allowed_directories=[<storage root>]; SET GLOBAL enable_external_access=false) and an Arc SQL-layer denylist of the literal functions read_parquet( and arc_partition_agg(. The sandbox correctly blocks reads outside the storage root (OS files, http:// SSRF), but it allowlists the entire multi-tenant storage root, and the SQL denylist still misses the rest of the DuckDB I/O family the original advisory enumerated. As a result, any authenticated token — including one with permissions: [] — can read or enumerate every other database's data within the deployment, defeating RBAC.

Verified at HEAD c08b892 (v26.06.1-36, includes 26.06.2). Confirmed still live; no later commit blocks these functions.

Root cause (three composing gaps)

  1. Sandbox scope is the whole storage root, not the tenant. internal/database/sandbox.go:111 allowlists cfg.LocalStorageRoot (default storage.local_path=./data/arc). Every database lives under it — internal/storage/util.go:33 GetStoragePath => <base>/<database>/<measurement>/**/*.parquet. Any in-root path is sandbox-permitted regardless of which database owns it.
  2. RBAC never inspects table-valued functions. checkQueryPermissions (internal/api/query.go:1181) extracts table refs via extractTableReferences, which skips any name followed by ( as a function (internal/api/query.go:1116); with zero refs it returns allow (:1213-1216). So parquet_scan(...), glob(...), parquet_metadata(...), read_blob(...), read_csv_auto(...) are never authorization-checked.
  3. The SQL denylist matches only the literal spelling. userSQLReadParquetPattern (internal/api/query.go:2087) is \bread_parquet\s*\(. DuckDB's documented alias parquet_scan( is not matched, and read_csv_auto/read_json/read_text/read_blob/glob/parquet_metadata/parquet_schema are not blocked anywhere. The fix author documented this very threat at internal/api/query.go:2061-2064 (“a user scoped to db1.m1 could read /data/db2/secrets/**/*.parquet”) but blocked only the literal read_parquet(.

Exploit (authenticated, any token incl. permissions:[])

POST /api/v1/query
Authorization: Bearer <token>
Content-Type: application/json
{"sql": "SELECT * FROM parquet_scan('./data/arc/<victim-db>/<measurement>/**/*.parquet')"}
  • ValidateSQLRequest passes (parquet_scan( is not read_parquet(, not a dangerous keyword, single statement).
  • checkQueryPermissions extracts 0 table refs (it is a function call) and allows.
  • convertSQLToStoragePaths finds no read_parquet literal and no bare FROM measurement to rewrite, so the query passes through unchanged.
  • DuckDB runs parquet_scan('<root>/<victim-db>/...'); the path is inside allowed_directories, so the other database's rows are returned.

glob('./data/arc/**/*') enumerates every database/measurement/file; parquet_metadata(...)/parquet_schema(...) leak column names and per-column min/max value statistics; read_blob(...) returns raw file bytes. All operate within the allowlisted root.

Proof (poc/poc_sandbox_alias_bypass.py, poc/OUTPUT.txt)

Reproduces Arc's exact sandbox config (allowed_directories=[<root>], enable_external_access=false) on DuckDB 1.5.x (Arc pins duckdb-go-bindings 1.5.1) with a victim parquet written under the root:

[BLOCKED ] read_blob OUTSIDE root            -> Permission Error: Cannot access file ...
[EXECUTES] parquet_scan victim (read_parquet ALIAS) -> [('tenant-VICTIM-row', 42)]
[EXECUTES] glob enumerate every db under root -> [('.../data/arc/victim-db/secrets/f.parquet',)]
[EXECUTES] parquet_metadata victim           -> [('leaked','tenant-VICTIM-row','tenant-VICTIM-row'), ('v','42','42')]

The sandbox blocks escape (as designed) but permits every in-root cross-database read.

Impact

Cross-database / cross-tenant…

Record
GHSA-93cm-2v4m-c56c
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-200, CWE-863
Updated
2026-11-04
NVD 6.5

Arc is an open, SQL-native time-series database for telemetry. Prior to the repository-verified 26.06.2 repair, the remediation of CVE-2026-47735 leaves a cross-database authorization bypass through DuckDB table-valued I/O functions. In internal/database/sandbox.go, allowed_directories uses cfg.LocalStorageRoot, configured by storage.local_path, while enable_external_access=false blocks access outside that entire multi-tenant root. GetStoragePath in internal/storage/util.go stores all databases beneath it. In internal/api/query.go, extractTableReferences skips names followed by an opening parenthesis and checkQueryPermissions allows queries with no extracted table references, including tokens with permissions: []. The userSQLReadParquetPattern denylist catches literal read_parquet( and the earlier protection also blocks arc_partition_agg(, but misses the parquet_scan alias and glob, parquet_metadata, parquet_schema, read_blob, read_csv_auto, read_json and read_text. A request to POST /api/v1/query using these unblocked functions passes ValidateSQLRequest and convertSQLToStoragePaths without tenant authorization, allowing reads and enumeration of other databases' time-series data, schema and per-column value-range statistics within the allowlisted root. The sandbox still blocks out-of-root OS files and HTTP SSRF, and the sibling SQLite token database outside the root is not exposed by this mechanism. The earlier 26.06.1 remediation does not comprehensively deny these I/O functions. Repository tag 26.06.2 contains the I/O-function repair and supplies the provisional remediation boundary; conflicting advisory affected-version statements require curator adjudication.

Record
CVE-2026-55098
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-200, CWE-863
Updated
2026-11-03
OSV 6.5

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

Arc is an open, SQL-native time-series database for telemetry. Prior to the repository-verified 26.06.2 repair, the remediation of CVE-2026-47735 leaves a cross-database authorization bypass through DuckDB table-valued I/O functions. In internal/database/sandbox.go, allowed_directories uses cfg.LocalStorageRoot, configured by storage.local_path, while enable_external_access=false blocks access outside that entire multi-tenant root. GetStoragePath in internal/storage/util.go stores all databases beneath it. In internal/api/query.go, extractTableReferences skips names followed by an opening parenthesis and checkQueryPermissions allows queries with no extracted table references, including tokens with permissions: []. The userSQLReadParquetPattern denylist catches literal read_parquet( and the earlier protection also blocks arc_partition_agg(, but misses the parquet_scan alias and glob, parquet_metadata, parquet_schema, read_blob, read_csv_auto, read_json and read_text. A request to POST /api/v1/query using these unblocked functions passes ValidateSQLRequest and convertSQLToStoragePaths without tenant authorization, allowing reads and enumeration of other databases' time-series data, schema and per-column value-range statistics within the allowlisted root. The sandbox still blocks out-of-root OS files and HTTP SSRF, and the sibling SQLite token database outside the root is not exposed by this mechanism. The earlier 26.06.1 remediation does not comprehensively deny these I/O functions. Repository tag 26.06.2 contains the I/O-function repair and supplies the provisional remediation boundary; conflicting advisory affected-version statements require curator adjudication.

Record
CVE-2026-55098
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-200, CWE-863
Updated
2026-11-06
OSVGHSA-93cm-2v4m-c56c 6.5

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735

Summary

The fix for CVE-2026-47735 (released 2026.06.1) is incomplete. It added a DuckDB sandbox (SET GLOBAL allowed_directories=[<storage root>]; SET GLOBAL enable_external_access=false) and an Arc SQL-layer denylist of the literal functions read_parquet( and arc_partition_agg(. The sandbox correctly blocks reads outside the storage root (OS files, http:// SSRF), but it allowlists the entire multi-tenant storage root, and the SQL denylist still misses the rest of the DuckDB I/O family the original advisory enumerated. As a result, any authenticated token — including one with permissions: [] — can read or enumerate every other database's data within the deployment, defeating RBAC.

Verified at HEAD c08b892 (v26.06.1-36, includes 26.06.2). Confirmed still live; no later commit blocks these functions.

Root cause (three composing gaps)

  1. Sandbox scope is the whole storage root, not the tenant. internal/database/sandbox.go:111 allowlists cfg.LocalStorageRoot (default storage.local_path=./data/arc). Every database lives under it — internal/storage/util.go:33 GetStoragePath => <base>/<database>/<measurement>/**/*.parquet. Any in-root path is sandbox-permitted regardless of which database owns it.
  2. RBAC never inspects table-valued functions. checkQueryPermissions (internal/api/query.go:1181) extracts table refs via extractTableReferences, which skips any name followed by ( as a function (internal/api/query.go:1116); with zero refs it returns allow (:1213-1216). So parquet_scan(...), glob(...), parquet_metadata(...), read_blob(...), read_csv_auto(...) are never authorization-checked.
  3. The SQL denylist matches only the literal spelling. userSQLReadParquetPattern (internal/api/query.go:2087) is \bread_parquet\s*\(. DuckDB's documented alias parquet_scan( is not matched, and read_csv_auto/read_json/read_text/read_blob/glob/parquet_metadata/parquet_schema are not blocked anywhere. The fix author documented this very threat at internal/api/query.go:2061-2064 (“a user scoped to db1.m1 could read /data/db2/secrets/**/*.parquet”) but blocked only the literal read_parquet(.

Exploit (authenticated, any token incl. permissions:[])

POST /api/v1/query
Authorization: Bearer <token>
Content-Type: application/json
{"sql": "SELECT * FROM parquet_scan('./data/arc/<victim-db>/<measurement>/**/*.parquet')"}
  • ValidateSQLRequest passes (parquet_scan( is not read_parquet(, not a dangerous keyword, single statement).
  • checkQueryPermissions extracts 0 table refs (it is a function call) and allows.
  • convertSQLToStoragePaths finds no read_parquet literal and no bare FROM measurement to rewrite, so the query passes through unchanged.
  • DuckDB runs parquet_scan('<root>/<victim-db>/...'); the path is inside allowed_directories, so the other database's rows are returned.

glob('./data/arc/**/*') enumerates every database/measurement/file; parquet_metadata(...)/parquet_schema(...) leak column names and per-column min/max value statistics; read_blob(...) returns raw file bytes. All operate within the allowlisted root.

Proof (poc/poc_sandbox_alias_bypass.py, poc/OUTPUT.txt)

Reproduces Arc's exact sandbox config (allowed_directories=[<root>], enable_external_access=false) on DuckDB 1.5.x (Arc pins duckdb-go-bindings 1.5.1) with a victim parquet written under the root:

[BLOCKED ] read_blob OUTSIDE root            -> Permission Error: Cannot access file ...
[EXECUTES] parquet_scan victim (read_parquet ALIAS) -> [('tenant-VICTIM-row', 42)]
[EXECUTES] glob enumerate every db under root -> [('.../data/arc/victim-db/secrets/f.parquet',)]
[EXECUTES] parquet_metadata victim           -> [('leaked','tenant-VICTIM-row','tenant-VICTIM-row'), ('v','42','42')]

The sandbox blocks escape (as designed) but permits every in-root cross-database read.

Impact

Cross-database / cross-tenant…

Record
GHSA-93cm-2v4m-c56c
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-200, CWE-863
Updated
2026-11-06
OSVGO-2026-6913 No score

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735 in github.com/basekick-labs/arc

Arc: DuckDB I/O aliases bypass database RBAC after CVE-2026-47735 in github.com/basekick-labs/arc

Record
GO-2026-6913
Updated
2026-11-06

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/basekick-labs/arc
Go
before 0.0.0-20260610131716-5dc8f53b70a3
0.0.0-20260610131716-5dc8f53b70a3

History

History
RecordedChangedSources
affected, aliasesOSV
publishedEUVD
affected, referencesOSV
affected, facts, referencesGitHub Advisories
factsNVD, OSV
first indexedCVE List, EUVD, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-55098 is a medium vulnerability (CVSS 6.5) in Basekick-labs Arc, published October 30, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 25th percentile. Fixed in github.com/basekick-labs/arc 0.0.0-20260610131716-5dc8f53b70a3.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open