Skip to content

chore: upgrade to cube v1.6.75 and fix High/Critical CVEs - #3

Open
jtroup wants to merge 713 commits into
stacklet/integrationfrom
elmo/easily-pet-thrush
Open

jtroup wants to merge 713 commits into
stacklet/integrationfrom
elmo/easily-pet-thrush

Conversation

@jtroup

@jtroup jtroup commented Oct 24, 2026

Copy link
Copy Markdown

what

Merge the upstream v1.6.75 release from the lts/v1.6 line into
stacklet/integration, then fix the High and Critical vulnerabilities
that a scan of the resulting image reports.

The merge brings the node:22.23.4 base image and upstream's lockfile.
Conflict resolution keeps the Stacklet dist/ overlay, the two
removed drivers (databricks-jdbc-driver, hive-driver), and the
logger patch. The patch now uses upstream's renamed message
parameter.

Follow-up commits:

  • Drop the npm tar replacement in the Dockerfile. npm 10.9.9 in the
    new base image bundles a newer tar, so the replacement would
    downgrade it.
  • Reset resolutions to upstream's. The carried 1.6.6 entries
    downgraded packages or forced incompatible majors against the new
    lockfile.
  • Refresh vulnerable packages in the lockfile within their declared
    ranges. Every new version in the lockfile is at least seven days
    old. Yarn 1 has no release-age setting, so we checked publish dates
    by hand and pinned the browserslist data packages, body-parser
    and on-finished back.
  • Add path-scoped resolutions where a fix crosses a declared range:
    tar 7.5.22 for the install-time tools that ask for ^6,
    basic-ftp 6.2.3 under get-uri, tmp 0.2.7 under
    external-editor, and toml 5.0.1 under snowflake-sdk.
  • In the runtime image, remove npm, npx and corepack, install
    libpython3.11 instead of libpython3.11-dev, and run
    apt-get upgrade.

why

The 1.6.6 image had 27 npm packages with High or Critical advisories,
plus advisories in its Node 22.22.0 runtime. That runtime predates the
fix for CVE-2026-111497, a remote code execution through Brotli
decompression.

The lts/v1.6 line gets upstream's backported fixes, and an upgrade
first means the dependency work happens once, against the current
lockfile. The upgrade alone fixed the Node runtime and a few npm
packages. The lockfile refresh and the scoped resolutions fixed the
rest.

The server never runs npm. Only the Playground's dashboard launcher
in dev mode does. Its bundled dependencies carried advisories of
their own. The native module links against libpython3.11.so, so the
runtime stage only needs the library, not the headers and toolchain
packages that -dev pulled in.

After these changes, the image has three npm packages with High or
Critical advisories: decompress, braces and http-cache-semantics.
None of them has a fixed release upstream. The remaining Debian
findings have no bookworm update.

testing

A local build of this branch passes the image smoke test and the
production logger check. Stacklet's Cube schema and local integration
suites pass against it, with cubejs/cubestore:v1.6.75. Relying on
the PR's image workflow for the CI build and push.

docs

No docs needed.


🤖 Generated with Claude Code

ovr and others added 30 commits May 27, 2026 14:51
…ube-js#10946)

Add a "Default dashboards" section to the Creator Mode embedding page
describing how admins share main-workspace content (read-only) with the
auto-created "All embed users" (all_embed_users) system group so embed
users see starter content immediately.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…to space (cube-js#10954)

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…0958)

Wrap the completed review body in a collapsed <details> block so only the verdict and issue counts stay visible at first glance. In-progress updates remain fully expanded so reviewers can still watch progress.
…ube-js#10959)

Previous wording let Claude interpret "review body" as excluding the todo checklist, which stayed visible at the top of the final comment as stale progress signal. Clarify that EVERYTHING — checklist included — collapses on the final update.
Post 👀 on the trigger comment as soon as the command is picked up, then
🚀 on success / 😕 on failure. Gives the user immediate feedback for
/bot-review and /bot-deep-review without having to open Actions.
…10966)

- Drop vendor-logo img from cards, add descriptions, switch to cols={3}
  (same pattern used on the Monitoring Integrations index)
- Remove orphan migration-leftover heading at the top
- Repoint REST API references to /reference/core-data-apis/rest-api

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PRs opened by the cursor coding agent were failing the review job
because claude-code-action rejects non-User actors unless they're in
allowed_bots.
…llation promise for Athena (cube-js#10953)

* feat: support distributed query cancellation in query queue and cancellation promise for Athena

Distributed Query Cancellation (QueryQueue):
- During the heartbeat interval, the executing node now checks if the
  queue item was removed externally (by another node calling cancelQuery
  or reconcile removing orphaned/stalled queries)
- If the queue item is gone and a cancel handler is registered locally,
  the local cancel handler is invoked, triggering actual DB query
  cancellation
- This closes the gap where cancellation from one node would remove the
  queue entry but the actual DB query kept running on the executing node

Athena Cancellation Promise (AthenaDriver):
- query(), memory(), stream(), downloadQueryResults(), and
  loadPreAggregationIntoTable() now return MaybeCancelablePromise with
  a .cancel() method
- Calling cancel() sets a flag that aborts the poll loop in
  waitForSuccess() and calls stopQueryExecution() on AWS Athena
- waitForSuccess() now accepts an optional isCancelled callback to
  detect cancellation during the poll loop
- The stream() release function now properly stops the Athena query
- This enables the query orchestrator to cancel in-flight Athena queries
  on timeout, manual cancel, or pre-aggregation cancellation via
  cancelCombinator

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor: use async/await instead of promise chaining in heartbeat callback

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor: use processCancel for external cancellation handling

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* feat: add REST API endpoint to cancel query by request ID

Add DELETE /cubejs-api/v1/running-query/:requestId endpoint that cancels
in-flight queries matching the given request ID across all SQL and
pre-aggregation queues.

- QueryQueue.cancelQueryByRequestId: scans queued queries and cancels
  those matching the request ID
- QueryOrchestrator.cancelQueryByRequestId: searches across all SQL
  query and pre-aggregation queues for all data sources
- OrchestratorApi.cancelQueryByRequestId: delegates to orchestrator
- ApiGateway: registers DELETE route with user auth middleware

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: add smoke test for query cancellation by request ID

- Add SlowQuery cube model that uses pg_sleep(30) to create a
  long-running query
- Add test that starts the slow query via HTTP load API with a
  known x-request-id, waits for it to enter the queue, then
  cancels it via DELETE /cubejs-api/v1/running-query/:requestId
- Verifies the cancel endpoint returns 200 with a result array

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: address review feedback — partial result bug, heartbeat error handling, sync throw

- AthenaDriver: throw on cancellation during row iteration instead of
  break, which would silently return truncated data
- AthenaDriver: move S3 config validation inside async IIFE in
  loadPreAggregationIntoTable to preserve rejected-promise semantics
- QueryQueue: wrap updateHeartBeat in try/catch to prevent unhandled
  promise rejections from connection failures in the async heartbeat
  callback

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* docs: document x-request-id header on /v1/cubesql and new cancel endpoint

- Add Headers section to /v1/cubesql documenting x-request-id header
  for custom request tracking and cancellation
- Add /v1/running-query/{requestId} endpoint documentation with
  parameter description, response format, and examples

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* docs: document x-request-id header on /v1/load endpoint

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: use REST SQL API (/cubesql) for cancel smoke test

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: resolve CI failures — remove test timeout arg and blank line padding

- Remove timeout argument from test() call — jest.setTimeout at the
  describe level already applies, and the types don't support the
  3-argument overload (TS2769)
- Remove blank line before closing brace (padded-blocks lint error)

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor: remove localCancelHandler from heartbeat cancellation detection

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* Revert "refactor: remove localCancelHandler from heartbeat cancellation detection"

This reverts commit ae4de19.

* docs: add comment explaining why localCancelHandler is needed

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: match cancel-by-request-id on UUID prefix, not exact span ID

The SQL API appends -span-N suffixes to request IDs on each
continue-wait retry, so the same logical query may have different
span suffixes in the queue. Strip the -span-N suffix before
comparing to match all queries from the same request.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: remove -span-1 suffix from test — SQL API appends it internally

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: assert cancelled query resolves with error within 40s

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: use /load API for cancel test and fix error assertion

The /cubesql endpoint's native transport has an internal retry loop
that re-submits cancelled queries with new span IDs, so cancellation
doesn't surface as an error to the client. Use /load instead where
the continue-wait loop is client-controlled.

After cancellation, /load returns { error: 'Continue wait' } since
the queue item is gone. Assert result.error is defined.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* feat: stop SQL API polling when HTTP client disconnects

When a client closes the connection to /v1/cubesql, the native
transport's continue-wait retry loop would keep polling indefinitely.

Fix: listen for res 'close' event in the gateway and mark the request
ID as closed. On each retry iteration, the sqlApiLoad callback checks
if the request was closed and throws 'Client disconnected' — a
non-continue-wait error that breaks the transport retry loop.

Closed request IDs are auto-cleaned after 5 minutes.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* Revert "feat: stop SQL API polling when HTTP client disconnects"

This reverts commit 1a33564.

* feat: stop SQL API polling when HTTP client disconnects (Rust-side)

When a client closes the HTTP connection to /v1/cubesql, the native
transport's continue-wait retry loop would keep polling indefinitely.

Fix: register a 'close' event listener on the Node.js response stream
from the Rust side (OnCloseHandler, modeled after OnDrainHandler).
When the stream closes, a oneshot channel fires. In handle_sql_query,
tokio::select! races the execute() future against the close signal.
If the client disconnects, the execute future is dropped, which
cancels the transport retry loop and all downstream operations.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: rewrite cancel test to use SQL API and verify pg_stat_activity

- Start slow query via /v1/cubesql (REST SQL API)
- Poll pg_stat_activity on the underlying Postgres to confirm
  pg_sleep is running
- Abort the HTTP connection (triggers Rust-side close detection)
- Cancel the query in the queue via DELETE /running-query/:requestId
- Poll pg_stat_activity again to confirm pg_sleep has stopped,
  verifying the query is no longer executing in Postgres

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: verify query cancellation via SQL API with pg_stat_activity check

- Start slow query via /v1/cubesql REST SQL API
- Confirm pg_sleep is running via pg_stat_activity on the underlying
  Postgres
- Abort HTTP connection (triggers Rust-side close detection)
- Cancel query in queue via DELETE /running-query/:requestId
- Verify second cancel returns empty (query is gone from queue)
- Clean up lingering pg_sleep via pg_terminate_backend in finally

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: increase pg_sleep to 90 seconds for cancel test reliability

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix: cargo fmt — fix import ordering and formatting

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test: add 2s wait between cancel calls to allow queue cleanup

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor: move extractRequestUUID to utils and reuse across QueryQueue and QueryCache

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* docs(admin): document app theme customization

Add an App theme page under Admin → Customization covering what can be
customized (accent/background/foreground colors, contrast, logo, fonts),
how to add fonts and a logo, and how to apply the theme to embedded
surfaces or across the entire Cube Cloud console. Register it in the nav
and cross-link it from the embed customization page.

* .
…s#10972)

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Document the conversational AI assistants for end users (dashboard
viewers and workbook authors). The Dashboard Agent page covers the
read-only Q&A panel on published/embedded dashboards; the Workbook
Agent page covers in-workbook authoring. Wires both into the
explore-analyze navigation.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ovr and others added 28 commits July 27, 2026 18:06
Validate every frontend message length before allocating, instead of trusting the client-supplied frame length:

* **Startup packet** (incl. SSLRequest/GSSENC/CancelRequest): capped at 10 KiB, in line with PostgreSQL's `MAX_STARTUP_PACKET_LENGTH`. Oversized frames are rejected with a protocol error before any allocation.

* **Authentication response** (e.g. the password message, read before the session is authenticated): capped at 64 KiB. PostgreSQL uses `PQ_SMALL_MESSAGE_LIMIT` (10,000 bytes) here, but CubeSQL accepts JWTs as passwords, which need more headroom.

* **Messages on authenticated connections**: capped at 16 MiB. PostgreSQL allows ~1 GiB (`PQ_LARGE_MESSAGE_LIMIT`), but CubeSQL has no COPY/bulk-ingestion path — the largest legitimate payloads are query texts (Query/Parse) and Bind parameters, and 10 MiB comfortably covers machine-generated SQL from BI tools.

(cherry picked from commit 8a4dd6f)
…ss (cube-js#11579)

Backport of the dev-token gate to the v1.6 LTS line.

`signedWithPlaygroundAuthSecret` unlocks developer affordances — meta
members hidden by `public: false` / access policies, generated SQL,
pre-aggregation and refresh-key debug info, request ids — and was set
purely from the token having verified against `playgroundAuthSecret`.
In Cube Cloud that secret signs every token a deployment mints, including
ones handed to end users and to external BI tools, so the signature alone
was never evidence that the bearer is a developer. Require a `dev-token`
entry in the token's `scope` as well; the control plane adds it only for
the developer-facing console surfaces and only for users with
deployment-manage permissions.

devMode is unaffected: all six consumers of the flag on this branch are
identical to master's, and every behavioural one already ORs with
`getEnv('devMode')`, so a local `cube dev` server keeps full visibility.
Authentication is unchanged — the scope gates what a playground-signed
token may see, not whether it verifies, so `/cubejs-system/v1/*` still
accepts any playground-signed token.


Claude-Session: https://claude.ai/code/session_018rhtueaPpiVVNkvA5rWv8X

Co-authored-by: Claude <noreply@anthropic.com>
…ube-js#11586)

`loadUserDefinedTypes` built its oid -> typname map with a reduce that
spread the accumulator on every row, copying the whole map n times. That
is quadratic and fully synchronous, so it blocks the event loop.

This went unnoticed while the query only selected `typcategory in ('U', 'E')`
(~20 rows on a stock Postgres). cube-js#11149 added `'A'` so that array-typed
columns get mapped, and Postgres auto-creates an array type for every
relation — the row count now scales with the number of tables in the
database, not with the number of actual user defined types.

Measured on postgres:16, `SELECT count(*) FROM pg_type WHERE typcategory
in ('U', 'E', 'A')`:

| tables in database | rows | spread reduce | in-place loop |
| ------------------ | ---- | ------------- | ------------- |
| 0                  |  313 |        6.3 ms |       0.12 ms |
| 5000               | 5313 |       2355 ms |       0.45 ms |
| ~20000             |   -  |      35116 ms |       1.10 ms |
…fined types (cube-js#11587)

cube-js#11149 needed array-typed columns to map to `text`, and selected all of
`typcategory = 'A'` to get there. Postgres creates a row type and an array
over it for every relation, so that selects one row per relation in the
database: the map stopped scaling with the types in use and started scaling
with the size of the catalog.

Those relation array types are only ever the type of a column for queries
that aggregate whole rows, which this driver does not issue, and a plain
composite column is already unsupported since `typcategory = 'C'` has never
been loaded. Arrays over a standalone `CREATE TYPE ... AS (...)` are kept,
they are real user defined types.

Measured on postgres:16 with 150 schemas of 20 tables, 3209 relations:

| query                | rows |
| -------------------- | ---- |
| typcategory in UEA   | 3317 |
| this one             |  108 |
…ovenance (cube-js#12300)

The v1.8.7 npm publish failed half-way: attempt 1 hit sigstore
TLOG_CREATE_ENTRY_ERROR (409) on 4 packages, and every retry then died
with EUNCOMMIT because the failed attempt left gitHead in every
package.json.

- lerna 10.0.1 -> 10.1.1: upgrades the npm publishing stack
  (libnpmpublish 11 -> 12, sigstore 4 -> 5, npm-registry-fetch 20)
- reset the working tree before each retry (`git checkout -- .`);
  `from-package` skips versions that are already published
- NPM_CONFIG_PROVENANCE: true. The `false` was a no-op anyway: lerna 10
  force-enables provenance after the OIDC token exchange for public repos

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ube-js#12302)

Fixes the v1.8.8 release failure in "Build other packages".

lerna 10.1.1 (cube-js#12300) pulled parse-url 9.2.0 into the root yarn.lock, which
depends on the deprecated stub @types/parse-path@7.1.0 (no index.d.ts). The
vizard apps' tsconfig set no `types`, so tsc auto-included every @types/*
from ancestor node_modules, including the monorepo root, and failed with
TS2688 for 'parse-path'; nx then bailed on 27 dependent packages.

`"types": []` in both vizard apps limits them to their own references;
vite/client is already pulled in via src/vite-env.d.ts.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ube-js#12400)

lerna 10 (cube-js#12300) pulled parse-url 9.2.0, which depends on the deprecated stub @types/parse-path@7.1.0 (no index.d.ts). lts/v1.6 sets no compilerOptions.types, so root tsc auto-included it and failed with TS2688, breaking unit and Build & Test :dev on every PR into lts/v1.6.

Pin @types/parse-path to 7.0.3 (last release with real typings) via root resolutions.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
 to v1.6) (cube-js#12398)

Backport of cube-js#12378 to lts/v1.6. eMudhra (emSign) intermediate CA keys
were compromised: webpki-roots 1.0.10 drops the emSign roots and
rustls-webpki 0.103.16 rejects chains containing the distrusted keys.

Lockfile-only. Unlike master, rustls 0.23.x on this branch still
depended on rustls-webpki 0.102, so rustls moves to 0.23.35 (the version
on master), also pulling rustls-pki-types 1.15.1 (and zeroize 1.9.1 in
Cube Store).

| Lockfile | rustls | rustls-webpki | webpki-roots |
|---|---|---|---|
| rust/cubestore | 0.23.7 → 0.23.35 | 0.102.2 → 0.103.16 | 0.26.1 → 0.26.11 + 1.0.10 |
| rust/cubesql | 0.23.11 → 0.23.35 | 0.102.5 → 0.103.16 | 0.26.3 → 0.26.11 + 1.0.10 |
| packages/cubejs-backend-native | 0.23.11 → 0.23.35 | 0.102.5 → 0.103.16 | 0.26.3 → 0.26.11 + 1.0.10 |
| rust/cube | — | 0.103.13 → 0.103.16 | 1.0.7 → 1.0.10 |

Co-authored-by: Maxim <maxim@cube.dev>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…js#12399)

Bump Node.js from 22.22.0 to 22.23.4 in all Docker images (dev, latest, latest-debian-jdk, local, testing-drivers) and .nvmrc on lts/v1.6.

Picks up the Node.js 22.22.2, 22.23.0, 22.23.2 and 22.23.4 security releases (33 CVEs across tls, http/http2, crypto, dns, zlib, brotli and the permission model, including High-severity CVE-2026-21637, CVE-2026-21710, CVE-2026-48618, CVE-2026-48933, CVE-2026-56846, CVE-2026-56848, CVE-2026-58043), plus OpenSSL 3.5.9, undici 6.29.1, c-ares 1.34.9 and NSS 3.131.1.

Also required by lerna 10.1.1 (cube-js#12300), whose engines field (^22.22.2) made yarn install --prod fail in the :dev image on 22.22.0.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Conflict resolution:
- latest.Dockerfile: upstream's node:22.23.4 base and LANG/LC_ALL; keep
  the Stacklet dist overlay and (for now) the npm tar replacement.
- cubejs-docker/package.json: upstream's 1.6.75 pins, still without
  databricks-jdbc-driver and hive-driver; keep our resolutions.
- yarn.lock: upstream's; regenerated against our resolutions in a
  follow-up commit.
- server-core logger.ts: upstream renamed prodLogger's msg parameter to
  message; update the carried "Performing query completed" check to match.
npm 10.9.9 in the node:22.23.4 base image bundles tar ^7.5.22; replacing
it with 7.5.3 would reintroduce fixed CVEs.
The carried resolutions were tuned to the 1.6.6 lockfile; against 1.6.75
several downgrade or force incompatible majors (tar, form-data,
@smithy/config-resolver, es5-ext). CVE fixes are redone against a fresh
scan. packages/cubejs-docker/yarn.lock is the root lockfile copied by
scripts/build-docker.sh.
body-parser@^1.19.0 (api-gateway, server) stayed on 1.20.3 with qs
6.13.0 after express's range moved to 1.20.8. 1.20.8 satisfies both
ranges, so both now share it.
@jtroup
jtroup requested a review from a team as a code owner October 24, 2026 01:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.