CVE-2026-55098

CVE-2026-55098 is a medium-severity incorrect authorization vulnerability in github.com/basekick-labs/arc (go), affecting versions < 0.0.0-20260610131716-5dc8f53b70a3. It is fixed in 0.0.0-20260610131716-5dc8f53b70a3.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

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

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 confidential read by any authenticated principal, including a least-privileged (permissions: []) token, on RBAC-enabled deployments. This is the same RBAC-bypass impact the original advisory described for read_parquet, still reachable via the alias and the unblocked I/O family. (Arc's SQLite token DB ./data/arc.db is a sibling of ./data/arc/ and is not in the allowlist, so it is not readable this way, the exposure is the time-series data of every database, plus its schema and value-range statistics.)

The application does not correctly enforce access controls, allowing a principal to access resources or operations beyond their granted permissions. Typical impact: unauthorized data access or execution of privileged operations.

CVE-2026-55098 has a CVSS score of 6.5 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.0.0-20260610131716-5dc8f53b70a3); upgrading removes the vulnerable code path.

Affected versions

github.com/basekick-labs/arc (< 0.0.0-20260610131716-5dc8f53b70a3)

Security releases

github.com/basekick-labs/arc → 0.0.0-20260610131716-5dc8f53b70a3 (go)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Per-request scope the sandbox to the requesting token's authorized database path(s): allowed_directories = ['<base>/<authorized-db>/'], so the file layer cannot cross the RBAC boundary regardless of which function is used. Alternatively, replace the function-name denylist with a strict allowlist of permitted table functions (alias-resolved, reject all others). A denylist of literal spellings is structurally fragile, this is the second alias/family miss after the original audit.

Frequently Asked Questions

  1. What is CVE-2026-55098? CVE-2026-55098 is a medium-severity incorrect authorization vulnerability in github.com/basekick-labs/arc (go), affecting versions < 0.0.0-20260610131716-5dc8f53b70a3. It is fixed in 0.0.0-20260610131716-5dc8f53b70a3. The application does not correctly enforce access controls, allowing a principal to access resources or operations beyond their granted permissions.
  2. How severe is CVE-2026-55098? CVE-2026-55098 has a CVSS score of 6.5 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of github.com/basekick-labs/arc are affected by CVE-2026-55098? github.com/basekick-labs/arc (go) versions < 0.0.0-20260610131716-5dc8f53b70a3 is affected.
  4. Is there a fix for CVE-2026-55098? Yes. CVE-2026-55098 is fixed in 0.0.0-20260610131716-5dc8f53b70a3. Upgrade to this version or later.
  5. Is CVE-2026-55098 exploitable, and should I be worried? Whether CVE-2026-55098 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-55098 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-55098? Upgrade github.com/basekick-labs/arc to 0.0.0-20260610131716-5dc8f53b70a3 or later.

Other vulnerabilities in github.com/basekick-labs/arc

Stop the waste.
Protect your environment with Kodem.