1.17.0: clear CRITICAL + transitive OSV findings via overrides (non-breaking)#446
Merged
Conversation
…es (non-breaking) Non-breaking security patch on the 1.x line so consumers can clear critical/high scanner alerts without waiting for or adopting the breaking 2.0.0 bump (requested on #386). Adds a package.json `overrides` block pinning transitive/dev deps to patched versions. Clears: - 2 CRITICAL: basic-ftp, form-data - HIGH/MED/LOW across the dev + transitive tree (ws, braces, micromatch, cross-spawn, serialize-javascript, @babel/*, js-yaml, ip-address, path-to-regexp, diff, ajv, nanoid, minimatch, follow-redirects, ...) No engine, runtime-API, or declared-dependency changes -> drop-in patch. The two remaining HIGH findings are on direct runtime deps whose fixes are SemVer-major (thrift 0.16->0.23, uuid 9->11); those, plus the engines >=18 bump, ship in 2.0.0 (#390). Verified with osv-scanner v2.3.8: only thrift + uuid remain (both "breaking change" per npm audit). Closes #386 Closes #263 Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Merged
6 tasks
Replaces the earlier hand-tuned transitive override list (which forced minimatch@5 globally and broke glob@7 with a "Cannot convert Symbol to string" crash) with a coherent approach: bump mocha 10.2->10.8.2 + eslint ->8.57.1 so the dev tree resolves patched transitive versions without version-split conflicts, and keep only the runtime/transitive overrides that don't fight the tree (basic-ftp, @75lb/deep-merge, ws, ip-address, form-data). Residual (deferred to 2.0.0, all require breaking changes): - thrift, uuid (HIGH) -> SemVer-major runtime bumps - serialize-javascript (dev-only) -> patched versions need Node >=20, which the non-breaking >=14 floor can't adopt; dev-only, not shipped. OSV: 0 CRITICAL, 0 transitive-fixable findings; only the above residual. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
The lint job runs `prettier . --check`; the hand-edited 1.17.0 CHANGELOG entry and package.json overrides block needed reformatting to pass. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
sreekanth-db
approved these changes
Jul 10, 2026
pull Bot
pushed a commit
to rebeccalarner/databricks-sql-nodejs
that referenced
this pull request
Jul 14, 2026
…lz4-napi (0 OSV findings) (databricks#390) * chore(sec): 1.17.0 — clear CRITICAL + transitive findings via overrides (non-breaking) Non-breaking security patch on the 1.x line so consumers can clear critical/high scanner alerts without waiting for or adopting the breaking 2.0.0 bump (requested on databricks#386). Adds a package.json `overrides` block pinning transitive/dev deps to patched versions. Clears: - 2 CRITICAL: basic-ftp, form-data - HIGH/MED/LOW across the dev + transitive tree (ws, braces, micromatch, cross-spawn, serialize-javascript, @babel/*, js-yaml, ip-address, path-to-regexp, diff, ajv, nanoid, minimatch, follow-redirects, ...) No engine, runtime-API, or declared-dependency changes -> drop-in patch. The two remaining HIGH findings are on direct runtime deps whose fixes are SemVer-major (thrift 0.16->0.23, uuid 9->11); those, plus the engines >=18 bump, ship in 2.0.0 (databricks#390). Verified with osv-scanner v2.3.8: only thrift + uuid remain (both "breaking change" per npm audit). Closes databricks#386 Closes databricks#263 Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * fix: coherent dev-toolchain for 1.17.0 overrides (mocha/eslint bump) Replaces the earlier hand-tuned transitive override list (which forced minimatch@5 globally and broke glob@7 with a "Cannot convert Symbol to string" crash) with a coherent approach: bump mocha 10.2->10.8.2 + eslint ->8.57.1 so the dev tree resolves patched transitive versions without version-split conflicts, and keep only the runtime/transitive overrides that don't fight the tree (basic-ftp, @75lb/deep-merge, ws, ip-address, form-data). Residual (deferred to 2.0.0, all require breaking changes): - thrift, uuid (HIGH) -> SemVer-major runtime bumps - serialize-javascript (dev-only) -> patched versions need Node >=20, which the non-breaking >=14 floor can't adopt; dev-only, not shipped. OSV: 0 CRITICAL, 0 transitive-fixable findings; only the above residual. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * style: prettier --write on CHANGELOG.md + package.json The lint job runs `prettier . --check`; the hand-edited 1.17.0 CHANGELOG entry and package.json overrides block needed reformatting to pass. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * 2.0.0: breaking security bump — Node >=20, thrift 0.23, uuid 11 (0 OSV findings) Completes the security cleanup that 1.17.0 (databricks#446) could not do without breaking changes. Stacks on the 1.17.0 overrides. Breaking: - engines.node >=14 -> >=20. Node 14/16/18 dropped (all past upstream EOL; 18 EOL 2025-04). >=20 is also the floor for the patched serialize-javascript (dev) and clears the kernel backend's own Node 18 requirement. - thrift ^0.16.0 -> ^0.23.0 (clears GHSA-r67j-r569-jrwp HIGH + GHSA-526f-jxpj-jmg2) - uuid ^9.0.0 -> ^11.1.1 (clears GHSA-w5hq-g745-h8pq HIGH 7.5); overrides pin thrift's transitive uuid at 11 (uuid 13 is ESM-only, breaks require()). Supporting: - typescript pinned 5.5.4 (uuid@11's .d.ts uses `export type` -> needs TS 5+; <5.6 to avoid @types/node Buffer-generic emit changing published .d.ts). - serialize-javascript override ^7.0.5 (needs Node >=20; now satisfied). - @types/node-fetch ^2.6.13. - OAuth.ts stub: cast Symbol.asyncDispose through any (ES2018 target predates the symbol; runtime Node 20+ provides it). - CI matrix -> [20, 22, 24]; e2e expanded to matrix; setup-jfrog lockfile URL rewrite (carried from the prior PR). Verified locally under Node 20: build clean, eslint clean, 1249 unit tests passing, osv-scanner v2.3.8 = No issues found. Closes databricks#370 Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * ci: trigger checks after clean force-update Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * test(ci): fix ts-node on Node 24+ (strip-types) and add Node 26 to matrix Two related changes for the widened 2.0.0 CI matrix [20, 22, 24, 26]: 1. Node >= 22.6 enables --experimental-strip-types, which on Node 24+ is the default loader for .ts and intercepts before ts-node. Its strip-only mode can't handle TypeScript features that emit code (constructor parameter properties), throwing "parameter property is not supported in strip-only mode" — even on files ts-node compiles fine. Both mocharc files now force `require: ts-node/register` and `node-option: [no-experimental-strip-types]` so ts-node owns .ts compilation on every supported Node. Verified locally: unit specs using parameter properties pass under Node 24. 2. Add Node 26 (current) to the unit + e2e matrices alongside the 20/22/24 LTS+active lines, for forward-compat coverage. Note: main previously only tested [14,16,18,20], so Node 22/24/26 were never exercised — this surfaced the strip-types issue as a latent, not a regression. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * test(ci): drop invalid node-option flag; ts-node/register alone fixes Node 24+ The previous commit added `node-option: [no-experimental-strip-types]`, but that flag doesn't exist before Node 22.6 — it's a "bad option" on Node 20, crashing the test process at startup and breaking a version that previously passed. `require: ts-node/register` alone is sufficient and version-agnostic: it registers ts-node's CommonJS require-hook so `.ts` resolves through ts-node on every supported Node, bypassing Node 24+'s built-in ESM strip-types path (whose strip-only mode rejects TS parameter properties). Verified locally: 34-test OAuth spec (uses parameter properties) passes on both Node 20 and Node 24 with require-only. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * test(ci): add ts-node/esm loader so Node 24+ handles .ts on the import() path require:ts-node/register alone was insufficient: mocha loads some specs (e.g. tests/unit/kernel/execution.test.ts) via import() (ESM), not require (CJS). On Node 24+ those ESM-loaded .ts files are grabbed by Node's built-in --experimental-strip-types, whose strip-only mode rejects TS parameter properties. Adding `loader: ts-node/esm` covers the import() path; the existing `require: ts-node/register` covers the require() path. Verified locally on BOTH Node 20 and Node 24: the kernel spec (ESM-loaded, uses parameter properties) and the OAuth spec (CJS-loaded) both pass — 102 passing on each. No version-specific node flags (which would crash Node < 22.6). Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * fix(deps): trim redundant overrides to minimal 3; fail-fast:false for diagnosis Overrides review (per "why override instead of bumping the parent?"): main's dependency tree already resolves basic-ftp (5.3.1), @75lb/deep-merge (1.1.4), ip-address (10.2.0), and form-data (4.0.6) to PATCHED versions via their parents (get-uri, table-layout, socks, node-fetch types) — verified main's lock has 0 OSV findings with no overrides at all. So those four overrides were redundant. Removed them. The minimal necessary override set is 3, each with a specific reason: - uuid ^11.1.1 — thrift@0.23 declares uuid ^13 (ESM-only, breaks require()) - ws ^8.18.0 — thrift@0.23 pulls ws ^5.2.3 (vulnerable; <8.17.1) - serialize-javascript ^7.0.5 — dev; only patched line, needs Node >=20 Lock unchanged by the trim (the 4 removed overrides matched default resolution), OSV still 0 findings. Also set fail-fast:false on the unit-test matrix so each Node version reports independently — the lz4 install failure needs per-version signal (lz4@0.6.5 is a 2021 native addon with no prebuilds; suspect it fails to build on Node 22+, which main never tested — main only ran [14,16,18,20]). Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * Revert override trim — restore 7-override set consistent with the lockfile The previous commit trimmed overrides to 3 but couldn't regenerate the lockfile to match (local npm proxy was failing tarball fetches), leaving package.json out of sync with package-lock.json → CI `npm ci` failed with EUSAGE "Missing: ip-address@9.0.5 from lock file". Also, the trim was partly wrong on the merits: ip-address's CVE fix (GHSA-v2v4-37r5-5v8g) is only in 10.1.1, but its parent `socks` caps it at `^9.0.5` — so without the override npm resolves the vulnerable 9.x. That override is genuinely required (parent won't allow the patched major), which is exactly when an override is the right tool. Restores the OSV-verified 7-override set matching the committed lock. `npm ci` clean, osv-scanner 0 findings. The fail-fast:false and ts-node strip-types fixes from earlier commits remain. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * lz4: replace unmaintained `lz4` with maintained `lz4-napi` (frame-compatible) Root cause of the Node 22+ CI failures: `lz4@0.6.5` (2021, unmaintained) is a node-gyp native addon with NO prebuilt binaries. It fails to compile on Node 22+, gets silently skipped as an optional dep, then tests that require('lz4') crash with "Cannot find module 'lz4'". Node 20 passed; 22/24/26 failed — confirmed via fail-fast:false per-version run. Replaces it with `lz4-napi@2.9.0` (maintained, napi-rs, ships prebuilds -> no local toolchain build, works on all Node versions). Verified locally that lz4-napi's compressFrameSync/decompressFrameSync are byte-compatible with the LZ4 *frame* format (magic 0x184D2204) the old package used and the Databricks server sends — round-trip and cross-decode both directions, incl. large buffers. lib/utils/lz4.ts now wraps lz4-napi behind the same { encode, decode } codec, so call sites are unchanged and the load-failure-tolerant contract is kept. Also fixes databricks#293 (deprecated Buffer() warning + xxhash build-resolution error, both from the old lz4 package). DIAGNOSTIC (this commit): CI temporarily uses `npm install` instead of `npm ci` so the JFrog registry resolves lz4-napi + its @lz4-napi/* platform packages (the dev npm proxy doesn't mirror those scoped packages, so the lock couldn't be generated locally). If CI resolves them, I'll pin a proper lock and restore `npm ci`. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * ci: complete lz4-napi lockfile, restore npm ci, fix prettier The lz4-napi swap CI run proved green on all Node versions (unit + e2e 20/22/24/26), confirming the maintained fork resolves and decodes LZ4 frames correctly where the old node-gyp `lz4` addon failed to build on Node 22+. Finalize databricks#390: - package-lock.json: regenerate against the dev proxy so the lz4-napi dependency tree is fully pinned (lz4-napi + 13 @antoniomuso/* platform packages + @node-rs/helper + @napi-rs/triples), with resolved: URLs the setup-jfrog action rewrites to JFrog. lockfileVersion stays 2. This makes the lock npm-ci-valid (the earlier stub was incomplete because @antoniomuso/* wasn't resolved). - main.yml: revert the diagnostic `npm install` back to `npm ci` in all three jobs (lint / unit-test / e2e-test) now that the lock is complete. - package.json: prettier — use the literal em-dash in the prepack message. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * review: address code-review findings on the lz4-napi swap From the Code Review Squad pass on databricks#390: - F1 (HIGH): package-lock.json — rewrite the 16 lz4-napi tree entries from the internal npm-proxy.dev.databricks.com back to registry.npmjs.org, matching the ~555 other lock entries so external forks/contributors can `npm ci`. CI's setup-jfrog step still rewrites npmjs.org → JFrog at install time. Integrity hashes are content-based, so the host swap is safe. - F2 (test): add a real, unmocked frame-compat suite (tests/unit/utils/lz4.test.ts) exercising the driver's codec against the actual lz4-napi — decodes a golden LZ4 frame produced by the independent `lz4` CLI (proving cross-encoder frame compat, not just self round-trip), plus binary round-trips incl. >single-block payloads. Runs on every Node version (import-based, no CJS-only skip). - F4 (HIGH): ArrowResultHandler / CloudFetchResultHandler error text said module `lz4` not installed — updated to `lz4-napi` so it no longer misdirects users to the removed package. - F6: README requirement Node.js 14 → 20, matching engines.node >=20. - F7 (perf): lz4-napi frame APIs already return owned Buffers; drop the redundant Buffer.from copy on the CloudFetch decode hot path. - F10: remove stale devDependency @types/uuid (uuid 11 is self-typed, unreferenced). F5 (matrix Node 26) is not applicable — Node 26 has GA'd (26.5.0 resolved and both unit+e2e legs passed), so the leg is real, not a permanently-red phantom. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> * review: gate real-codec lz4 tests on availability, not the environment Follow-up to N1 (devils-advocate, conf 85): the `is available` case asserted getLZ4() is always defined, which tests the environment rather than the code and breaks the module's deliberately-optional contract. lz4-napi ships prebuilds for mainstream platforms but not every arch (linux-ppc64le/s390x/…), and `npm ci --omit=optional` also yields undefined — on any of those the whole unit run would fail. Move the availability check into a `before()` that `this.skip()`s (with a visible console.warn) when the binding can't load, and drop the unconditional assertion. The frame-compat cases now test the codec when present and degrade gracefully when absent. CI's linux-x64 matrix always has a prebuild, so the golden-frame and round-trip coverage still runs there on every push. Co-authored-by: Isaac Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> --------- Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Non-breaking security patch on the 1.x line. Adds a
package.jsonoverridesblock pinning transitive/dev dependencies to patched versions, so consumers can clear their critical/high scanner alerts without waiting for or adopting the breaking2.0.0bump (#390).This directly answers the request on #386 for a patch on the current major.
What this clears
basic-ftp,form-dataws,braces,micromatch,cross-spawn,serialize-javascript,@babel/*,js-yaml,ip-address,path-to-regexp,diff,ajv,nanoid,minimatch,follow-redirects,@75lb/deep-merge,flatted,picomatch,brace-expansion.What this intentionally does NOT change (no breaking changes)
engines.nodeunchanged (>=14)npm i @databricks/sql@1.17.0clears the alerts with zero migrationResidual (deferred to 2.0.0)
Two HIGH findings remain — on direct runtime deps whose fixes are SemVer-major and therefore breaking:
thriftuuidnpm auditconfirms both are "breaking change" fixes, which is why they're not in this patch.Verification
thrift+uuidremain (the two 2.0.0 items); all CRITICAL + transitive/dev findings cleared.Test plan
Closes #386
Closes #263
This pull request was AI-assisted by Isaac.