Repository navigation
feat(web): refuse server function calls from another build - #4215
Conversation
- Add `buildId` to `configureServerFunctionsClient` and `configureServerFunctionsServer`. - The client sends `X-Server-Function-Build` on every call that is not GET-encoded. - A server with a different id answers 409 with its own id and does not run the function. - The client rejects with `versionSkew: true`, so an integration can reload the page. - GET-encoded reads stay header-free, so caches and preloads still match them by url. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 89a61a7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 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 |
Merging this PR will not alter performance1 warning
Comparing Footnotes
|
Generated by Claude Code |
- Remove `buildId` from the client. The client runtime no longer sends the header, so it adds no bytes. - The 409 also carries the unknown-function label, so the client rejects with `unknownFunction: true`, the same as the 404. - Remove `BUILD_HEADER` from the public exports. The integration adds the header through `prepareRequest`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Moved the client half out of the transport, as suggested.
Two open questions for the integration side:
🤖 Generated with Claude Code |
The unknown-id 404 (#3110) catches a function that a deploy removed or renamed. It cannot catch one whose id survived the deploy but whose arguments or result changed shape, because ids hash the file path and the name, not the body. This adds an opt-in build id check on the server for that case. It is the core version of solidjs/solid-start#2363.
Changes
BUILD_HEADER(X-Server-Function-Build) to the shared layer. It is not exported from either entry.buildIdto the server config. A call whose header names another build gets409, with the server's id under the same header andCache-Control: no-store. The arguments are not parsed and the function does not run.X-Server-Function-Unknown). The client rejects it withunknownFunction: true, the same as the unknown-id 404. There is one skew signal for integrations to check.prepareRequest. Platform skew protection, such as pinning a deployment by header or cookie, fits the same hook.buildIdchecks nothing.10-server-functions.md.Testing
test/server/server-functions-build-id.spec.tsx(6 tests) runs against the built bundles. It covers the refusal, a matching build, a call without the header, a server without an id, the client error flag through aprepareRequesthook, and a matching build through the client.link-claim.spec.tsxandlowercase-on-attribute.spec.tsx. These fail the same way without this change in my local setup, which has a stale compiler build.🤖 Generated with Claude Code