Repository navigation
fix(deps): bump knex to 3.2.9 for the search_path SQL injection - #1024
Conversation
AIKIDO-2026-10469: knex 0.0.1-3.2.8 interpolates values passed to searchPath for the Postgres dialect into generated SQL without validating or escaping them. nostream declares knex 2.4.2, so the image ships a vulnerable copy. 3.2.9 is the smallest published version that contains the fix (#6411 escapes double quotes in searchPath), and it is the version Aikido names. 3.2.10 and 3.3.0 carry no further security fix; 3.3.0 also lands a fix to something other than this advisory, so the smallest bump above the fixed version is the one that changes the least. The repo never sets searchPath: grep -rn "search_path" src/ finds no match, so the vulnerable code path is not reachable here. The bump is still taken, because the vulnerable dependency should not ship. knex 3.0.0 drops Node < 16 (the repo requires >=24.14.1) and 3.2.0 tightens the RawBinding type. That surfaced one compile error: benchmark-queries.ts passed "bindings as readonly unknown[]" to db.raw(), and an assertion to unknown no longer satisfies RawBinding. Dropping the assertion is the fix, not a new one - toSQL().bindings is already the accepted type, and the emitted JavaScript is byte-identical with and without the assertion.
🦋 Changeset detectedLatest commit: eb304b8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
[Medium impact] The PR appears safe to merge; no actionable issues were found.
|
Coverage Report for CI Build 41318001795Coverage remained the same at 77.419%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Brings 142 commits from main onto the rewrite line, which had 30 of its own. Three files conflicted and each resolution keeps the side that matches the code this branch actually runs: - .github/workflows/checks.yml — union. The rewrite's path filters for resources/ and crates/ stay; main's two globs (.github/workflows/** and .github/scripts/**) are added to the src filter, because a unit test reads those files and #965 skipped the suite a release.yml change broke. - CONFIGURATION.md — the rewrite's mirroring.static[] rows stay. main removed the setting along with its TypeScript worker; this branch still parses it in nostream-config (settings.rs, guided.rs, validate.rs and the mirror_filters test), so main's "removed" row describes a worker that never existed here. - resources/default-settings.yaml — the rewrite's connection.maxConnectionsPerIp block stays, and main's comment about period units is kept above the rateLimits list it describes. The knex 3.2.9 bump from #1024 arrives with the merge, so the standalone PR that carried the same fix onto this branch is superseded.
Bumps
knexfrom 2.4.2 to 3.2.9 for AIKIDO-2026-10469: knex 0.0.1–3.2.8 interpolates values passed tosearchPathfor the Postgres dialect into generated SQL without validating or escaping them, so a value an attacker influences becomes an injected identifier. This repository is a Postgres user and declaresknex2.4.2, so the image ships a vulnerable copy.Version chosen: 3.2.9
3.2.9 is the smallest published version that contains the fix — #6411, "escape double quotes in searchPath to prevent SQL injection" — and the version the advisory names. 3.2.10 and 3.3.0 add no further fix for this advisory, so 3.2.9 is the smallest change that removes it.
Breaking changes read from the release notes:
node >=24.14.1, so nothing to do here.RawBinding, "types no longer allow knex to be called without tablename",firston 0 matches documented, migration lifecycle hooks). One compile error surfaced, fixed below.RETURNINGfix andDELETE … LIMITsupport in MySQL. Neither applies to this repo.Nothing in
src/or the migrations needed a runtime change:pnpm build:check, the full unit suite and the integration suite (CI) pass unchanged apart from the typing fix.The one code change
src/scripts/benchmark-queries.tspassedbindings as readonly unknown[]todb.raw(). An assertion tounknownno longer satisfies knex 3'sRawBinding, so the assertion is dropped:const { rows } = await db.raw<{ rows: { 'QUERY PLAN': ExplainResult[] }[] }>( `EXPLAIN (ANALYZE, BUFFERS, VERBOSE, FORMAT JSON) ${sql}`, - bindings as readonly unknown[], + bindings, )toSQL().bindingsis already the accepted type, so this removes an assertion rather than adding one. It is a compile-time change only: the emitted JavaScript is byte-identical with and without the assertion, verified by building both ways and comparingsha256sum dist/src/scripts/benchmark-queries.js—df144e2b…df1ddain both builds.search_path: not usedNo match, in
src/or anywhere in the repository outsidenode_modules. nostream never passes an identifier tosearch_path, so the vulnerable code path is not reachable through this codebase. The bump is still required: the vulnerable dependency should not ship, and reachability can change with a dependency, not just with our source.Verification
The 3 warnings are pre-existing
lint/style/useBlockStatementswarnings intest/unit/ci/*.spec.ts; none are in a file this PR touches.Exits 0 with no output. Resolved dependency:
The
docker:test:integrationsuite (cucumber against a real Postgres) is not runnable from this sandbox; CI's integration job covers it and this PR does not change its inputs beyond the dependency.Note on the lockfile
knex 3.2.9 declares an optional peer dependency on
pg-query-stream ^4.14.0; this repo pinspg-query-stream4.3.0 as a direct dependency, so pnpm resolves the peer to 4.3.0. That version is optional (used only by knex's.stream()), the resolution installs cleanly with--frozen-lockfile, and nothing here calls it. Bumpingpg-query-streamis out of scope for a security bump and is not done here.rewrite/mainstill needs the same bumpChecked separately, as requested.
rewrite/mainstill declares"knex": "2.4.2"and still imports knex at runtime:It also still ships the TypeScript server and its
test:unitsuite inchecks.yml. The same bump is therefore being opened againstrewrite/mainas its own PR rather than mixed into this branch.Changeset
.changeset/knex-3-2-9-security.md—"nostream": patch.This is dependency hygiene: the advisory is not reachable in this codebase today.
Summary by CodeRabbit
Bug Fixes
Maintenance