fix(web): close the server-function boundary defects - #3254
Conversation
🦋 Changeset detectedLatest commit: 7d5e66f The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
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 |
Twenty-two verified defects across the argument decode, the result graph, the single-flight fold, the invocation seams, the no-JS flash road and the client transport. Each one was pinned by a test proven red on f0f7531 before any source changed; the twenty-five new specs and the eight source files land together. Fixes solidjs#3232 Fixes solidjs#3233 Fixes solidjs#3234 Fixes solidjs#3235 Fixes solidjs#3236 Fixes solidjs#3237 Fixes solidjs#3238 Fixes solidjs#3239 Fixes solidjs#3240 Fixes solidjs#3241 Fixes solidjs#3242 Fixes solidjs#3243 Fixes solidjs#3244 Fixes solidjs#3245 Fixes solidjs#3246 Fixes solidjs#3247 Fixes solidjs#3248 Fixes solidjs#3249 Fixes solidjs#3250 Fixes solidjs#3251 Fixes solidjs#3252 Fixes solidjs#3253
7d5e66f to
a56c001
Compare
|
Superseded on Every fix here landed in your own commits, and in three places yours is the better call:
I've re-run my own repros against The three dispositions I did not get my way on are noted and not re-litigated here: the response-leg strip (#3233), the flight-slice preflight (#3243), and the flash refusal statuses (#3250). #3239 is the one still open. Thanks for turning these around so quickly. |
|
Closing the loop with the full disposition, now that everything from this sweep has landed. Thanks again @frenzzy — 22 filed issues, and the triage upheld most of them. The complete record lives in the conformance matrix ( Fixed on #3239 (flash cookie confidentiality) got the deepest treatment: the payload is now AES-GCM encrypted, always, under a key derived from a deployment-wide secret ( Ratified as-is after review (closed, no code change): #3240 (entry-only Rejected as proposed: #3233 (decode-boundary stripping destroys legitimate The wholesale form of this PR was never mergeable — 43 files across independent concerns — but as an audit it was excellent: it drove a permanent conformance matrix for the server-function protocol that future changes get checked against. That's a better legacy than a merge. |
Twenty-two verified defects in the server-function runtime, fixed together because they were found together and because three of them share a hunk.
How this was built
Every defect was reproduced first, then pinned by a spec proven red on
f0f7531bbefore a line of source changed. The fixes were written independently, in eight separate checkouts, and only then merged into one tree — so the overlap between them is measured rather than assumed.That measurement is why this is one PR and twenty-two issues rather than twenty-two PRs. Each of the 32 source hunks was reverted one at a time, rebuilt, and the suite re-run to record which specs go red:
stripUnsafeKeysinserver-functions/src/shared.tsreddens the new response-decode specs (7), the new flash-decode specs (2) and the already-shipped argument-road specs (server-functions-proto-keys,open-gaps). Three decode roads, one guard — which is the fix: the strip moves from a caller toextractBody, the boundary all three share.isJSONSafe's-0and own-names edits sit three lines apart in one function with the same-sounding rationale, but redden disjoint specs.Verification
f0f7531bvitest runvitest run --config vite.config.server.mjsvitest run --config vite.config.hydrate.mjstsc --project tsconfig.build.jsonandtsconfig.test.jsonclean;prettier --checkclean on every touched file. No pre-existing test was edited or deleted — where a fix first reddened one, the fix was rewritten, not the test.What is deliberately not here
Several findings were left unfixed with the reasoning recorded in the issues rather than forced into a patch: non-enumerable accessors on an
Errorcarrier (closing that means invoking hidden accessors, the hazard47995412removed); theframes/transport's own decode leg, which bypassesextractBody; a sync-iterable class instance, whose carrier properties are dropped by a different function. Two judgement calls are flagged in their issues as yours rather than asserted here — whetherGET()'s contract should say that a declared read is a navigable document, and whether the slowloris time bound belongs in core or in the adapter.Issues
GET()grant governs an id, not the function it was granted to #3237 — AGET()grant governs an id, not the function it was granted towrapInvocationoption that is not a hook removes the configured authorization gate #3238 — AwrapInvocationoption that is not a hook removes the configured authorization gateSameSite, no lifetime and no__Host-prefix #3239 — The flash cookie carries the submission with noSameSite, no lifetime and no__Host-prefixwrapInvocationnever sees the calls the dispatched body makes #3240 — A per-handlerwrapInvocationnever sees the calls the dispatched body makesnew fn()enters a server function body past every guard the apply trap holds #3242 —new fn()enters a server function body past every guard the apply trap holdsprovideEvent's exactly-once contract is enforced on HTTP dispatch and nowhere else #3246 —provideEvent's exactly-once contract is enforced on HTTP dispatch and nowhere elsetransformResultsees every failure an author shaped by hand and none that happen to the app #3247 —transformResultsees every failure an author shaped by hand and none that happen to the appurl, so the cookie is discarded whole while claiming it fit #3249 — The degrade ladder bounds every field buturl, so the cookie is discarded whole while claiming it fit/_server/<id>with everything the user typed gone #3250 — A form navigation refused before dispatch is left on/_server/<id>with everything the user typed goneReferer#3252 — A redirecting mutation loses single-flight whenever the page sends noReferer-0takes the JSON fast path and arrives as+0#3253 —-0takes the JSON fast path and arrives as+0