Skip to content

fix(deps)!: hono ^4.13.16 and @hono/node-server ^2.1.6 clear seven public advisories; a request path holding a backslash is answered 400 - #33225

Draft
objectstack-fleet[bot] wants to merge 2 commits into
mainfrom
claude/project-thread-dsyzlu
Draft

objectstack-fleet[bot] wants to merge 2 commits into
mainfrom
claude/project-thread-dsyzlu

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #33211

Clause-②: yes (narrowing) — @hono/node-server 2.1.6 answers 400 Bad Request to a request whose path (the part before ?) holds a backslash, before any route runs; up to 2.1.5 the backslash was rewritten to / and the request reached the route that path names. No other status, header, body or error text of ours moves, and the request-body limit (413 PAYLOAD_TOO_LARGE) answers as before.
Metadata-protocol: none
Skills-docs: none — no skill under skills/** and no page under content/docs/** teaches request-path spelling at the HTTP door.

⚠️ Owes a contract review at CONTRACT_REVIEW_TIER (narrowing) from the new review agent. Seat contract reviews are paused until that agent is online (maintainer instruction, 2026-11-14 04:37Z), so this draft is not landed before that review is on record.

维护者速读

  • 改了什么:把 HTTP 底座 hono 升到 ^4.13.16、@hono/node-server 升到 ^2.1.6(锁文件实际落在 4.13.18 / 2.1.8),工作区里这两条 override 的目标同步抬高,7 个包的声明版本一起改,下游安装也会拿到修复版。
  • 为什么改:每天的依赖安全扫描在 main 上是红的,18.4.0 带着 7 条公开漏洞(6 中 1 低),每个部署的 HTTP 栈都在用这两个包;修复版已发布,不加豁免。
  • 风险与回滚:patch 级。唯一会变的回答:URL 路径里带反斜杠(如 /api/v1\health)的请求,现在直接回 400,以前会被改成 / 继续路由;浏览器和常见 HTTP 库本来就不会发这种请求。请求体上限的 413 不受影响。回滚 = revert 本 PR。
  • 先看:pnpm-workspace.yaml 的两条 override 和注释;.changeset/33211-hono-security-bump.md(BREAKING 说明);packages/plugins/plugin-hono-server/src/request-target-backslash.pin.test.ts。
  • 两分钟验证:pnpm --filter @objectstack/plugin-hono-server exec vitest run src/request-target-backslash.pin.test.ts,预期 3/3 通过(带反斜杠 400,不带 200,? 后的反斜杠 200)。
  • 需要你做的:无,等新的评审 agent 做完契约复审后由席位落地。

What changes

Tests

All at commit 76bc2487 on a closure rebuilt with declarations (turbo run build --filter='./packages/**' --filter='@objectstack/dogfood^...' --filter='./ui/**', 118/118). The merge of origin/main at 56fd8aeb brought no package.json, lock or workspace change, so nothing was re-run after it.

Suite (pnpm --filter PKG test) Files Tests
@objectstack/plugin-hono-server (incl. #33172 body-limit.test.ts, request-body-refusal.test.ts, the new pin) 41/41 540 passed
@objectstack/hono (incl. hono-body-refusal.test.ts) 14/14 258 passed
@objectstack/rest 409/409 8346 passed, 332 skipped
@objectstack/runtime 598/598 10645 passed, 19 skipped
@objectstack/plugin-auth 269/269 5114 passed, 10 skipped
@objectstack/plugin-approvals 119/119 1632 passed
@objectstack/client 58/58 812 passed
@objectstack/plugin-webhooks 25/25 296 passed
@objectstack/trigger-api 3/3 73 passed
  • New pin request-target-backslash.pin.test.ts: 3/3.

Acceptance notes

  • OSV. The scheduled run 43549452164 lists exactly the seven rows. api.osv.dev is refused by this container's proxy, so the scan itself is not run locally: NOT MEASURED locally, read from this PR's Validate Dependencies run. After the bump pnpm-lock.yaml holds only hono@4.13.18 and @hono/node-server@2.1.8, both at or above every advisory's fixed version. osv-scanner.toml is unchanged (no new exemption).
  • Upstream changes read (npm tarball diffs, 4.13.12 → 4.13.18, 2.1.5 → 2.1.8). Body reading is untouched: hono/utils/body and node-server's request-body path did not change, so fix(plugin-hono-server, hono)!: a request body over the server's limit is answered 413 PAYLOAD_TOO_LARGE and is not read past the limit #33172's request-body limit answers as before (pins and dogfood below). Changes that do not move an answer of ours: node-server websocket-upgrade target checks (we run no node-server upgrade), response-stream cancel on a destroyed socket, hono RegExpRouter wildcard/middleware matching rewrite and getPath handling of a malformed % (the suites below stay green, no route of ours moved), query-key lookup for crafted queries, and csrf / validator / hono serve-static / .mount() / cookie / accepts changes in middlewares we do not import.
  • Ruling grep (ruling|Ruling-ref|maintainer|⛔) on the touched surface: hits only in pnpm-workspace.yaml's better-auth and scim notes, which do not govern the hono lines. No hits in the touched package.json files.
  • Serial. No open PR touches the hono pins, the two override lines or the lock's hono entries (checked before push).

Verification

Ablation of the backslash pin (node-server's refusal put back to 2.1.5's behaviour)
  • Mutation: in the installed @hono/node-server@2.1.8 dist/index.mjs (what plugin-hono-server resolves; no vitest alias), the line if (query === -1 || backslash < query) throw new RequestError("Backslash in request path"); replaced by a comment. On disk: anchor count 0, marker count 1.
  • Red: 1 failed | 2 passed (3). The backslash request was routed: Received: "HTTP/1.1 200 OK ... {\"success\":true,\"data\":{\"id\":\"t_1\"}}" at request-target-backslash.pin.test.ts:53.
  • Restored by copy, sha256 compared equal (1c062cab…), re-run 3 passed (3).
Dogfood boot (`pnpm dev:crm -- --fresh -p 38421`, Console built with `pnpm console:build`)
  • Page: GET / → 200 text/html, redirected to /_console/, title ObjectOS.
  • Sign-in as the seeded dev admin → 200. API read: GET /api/v1/data/crm_account?limit=2 → 200 with records.
  • Oversized body: an 11 MiB JSON POST /api/v1/data/crm_account/query → 413 "code":"PAYLOAD_TOO_LARGE"; a small body on the same door → 200.
  • Raw request lines: GET /api/v1/health → 200 OK; GET /api/v1\health → 400 Bad Request; GET /api/v1/health?x=a\b → 200 OK.
  • The server resolved @hono/node-server@2.1.8_hono@4.13.18. Server stopped afterwards.
Gates (derived at 76bc248, 79 commands)
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 79 commands; each run with stdin from /dev/null, exit codes recorded before any pipe: 79 × exit 0.
  • --ran reconciliation: 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: every line carries an exit code, none is 3).
  • A first gate pass ran while a declaration-less ui build was rewriting shared dist/ (5 prerequisite/resolve reds: check:skill-examples, check:dts-closure, check:dual-build-cjs-loads, check:i18n, check:lean-entry-closure). That pass was discarded, the closure rebuilt with declarations, and all 79 re-run green.
  • Server-lane rule: pnpm lint (eslint . --no-inline-config) at 56fd8aeb → exit 0.
  • OSV scan: NOT MEASURED locally (api.osv.dev refused by the container proxy); this PR's Validate Dependencies run is the reading.
Full dogfood battery at 56fd8ae (owed by the narrowing arm)
  • pnpm --filter @objectstack/dogfood test under the verify lock, no shard, no path: VERDICT command-exit 1 · Test Files 1 failed | 465 passed | 1 skipped (467) · Tests 6 failed | 3932 passed | 31 skipped (3969).
  • The one failing file is test/print-service-render.dogfood.test.ts (6 of 8: "The print page did not finish rendering within 30 s … the console never showed a print page for the record"). It runs only where a built Console and a Chromium are both present; CI's dogfood job builds no Console, so CI skips it. This container had both because the dogfood boot above built the Console.
  • Not this change: the same file, alone, with the installed hono / @hono/node-server contents swapped back to main's 4.13.12 / 2.1.5 (copied from the npm tarballs, restored afterwards, tree hashes compared equal), fails the same 6 tests the same way (6 failed | 2 passed (8)). Noted for the seat, not filed by this card.

Both releases fix public advisories that the scheduled OSV audit reports
against the locked hono 4.13.12 and @hono/node-server 2.1.5. The two
workspace override targets lift in lockstep with the declared ranges, so the
workspace lock and a downstream install both land on the fixed releases.

@hono/node-server 2.1.6 answers 400 to a request whose path holds a
backslash, where 2.1.5 rewrote it to '/' and routed it. A real-listener pin
records that answer beside the same route without the backslash.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibyksdYkFdXq4KWWzwP
@github-actions github-actions Bot added size/m dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 2 changed file(s) yielded no anchor (packages/plugins/plugin-auth/package.json, packages/plugins/plugin-hono-server/package.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 2 changed package(s)).

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/plugins/plugin-auth/package.json, packages/plugins/plugin-hono-server/package.json) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 27 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json a3a3cea6065fe90a7f609dc682298bce52d89ffd → packageMentionDocs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(deps): hono 4.13.12 → 4.13.16 and @hono/node-server 2.1.5 → 2.1.6 — seven public advisories fail the scheduled OSV audit on main

2 participants