Start mode: generated entries render without the CSP nonce, and there is no per-request seam to supply one
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 5/5
- 預估耗時
- 一週以上
- 新手友好度
- 35/100
- Issue 類型
- 功能
- 描述清晰度
- 描述清楚
- 活躍度
- 活躍
- 技術堆疊
- typescript
研究方向
Start in src/ssr/index.ts at the generated-entry sites around lines 932 and 1394, then inspect the nonce handling near line 1279 and the Fetchable around line 1461. Reproduce the issue in examples/start-ssr with the two handleRequest calls; done means generated and authored entries propagate resolved nonce values, dev-injected tags are covered, and the object CSPNonce form no longer throws.
由索引模型根據 Issue 內容生成。
描述
Problem
A strict CSP (script-src 'nonce-…' 'strict-dynamic', no 'unsafe-inline') cannot be served with Start mode's generated entries. The only nonce input is handleRequest(request, { nonce }), added in #311, and it only reaches two tags: the injected client-entry <script> and the post-flush redirect fallback.
The generated entry renders with a fixed { manifest } and ignores the context it receives:
So even when a host passes nonce, renderToStream never gets it. The hydration bootstrap (_$HY), the streamed data and swap scripts and the modulepreload links all go out without a nonce, and the page does not hydrate under the policy.
There is also no way to supply the nonce from inside the app:
- Deployments that dispatch through the default Fetchable (Nitro calls
mod.fetch(req)) never pass options. That is intentional, since the second argument of a Fetchable belongs to the host: https://github.com/solidjs/solid-vite-plugin/blob/e4cdee454dbe0a99d9cb566d1dba72a93a9dcac1/src/ssr/index.ts#L1461 start.middlewareis the natural place to generate the nonce and set theContent-Security-Policyheader, but it only sees(request, next). The options bag is fixed before the chain runs.start.setupreturns a component andstart.renderModereturns a mode, so neither can change the stream options.@solidjs/webonly reads the nonce from therenderToStreamoptions, not from the request event orlocals.
Today the workaround is hand-written entry-server / entry-client files that pass nonce to renderToStream. Entries come in pairs, so both have to be written, and authored entries also give up the generated DefaultErrorBoundary. SolidStart had a per-request seam for this (createHandler(fn, (event) => ({ nonce })), see solidjs/solid-start#2252). #311 ported the client-entry part of that change.
A related bug: the object form CSPNonce that @solidjs/web accepts ({ script, style }) throws in the client-entry transform, because it escapes the value as a string:
TypeError: value.replace is not a function
Reproduction
With @solidjs/vite-plugin 3.0.0-next.47 and @solidjs/web 2.0.0-rc.13, in examples/start-ssr:
const html = await (await handleRequest(new Request('http://localhost/'), { nonce: 'abc' })).text();
// only the client-entry <script> carries nonce="abc";
// the _$HY bootstrap, the data scripts and the modulepreload links do not
await handleRequest(new Request('http://localhost/'), { nonce: { script: 'abc', style: false } });
// TypeError: value.replace is not a function
Proposal
A start.nonce option that follows the renderMode module convention. The option names a module that default-exports (event) => CSPNonce | undefined | Promise<…>. The handler resolves it after the middleware chain, next to resolveRenderMode, so a middleware can generate the nonce, set the header and store it on event.locals:
solid({ start: { middleware: './src/middleware.ts', nonce: './src/nonce.ts' }, ssr: true });
// src/nonce.ts
export default (event: RequestEvent) => event.locals.nonce as string | undefined;
The resolved value (or handleRequest's nonce, which keeps precedence) would go to:
- the generated entry's
renderToStream; - the client-entry tag and
createSSRResponse, both throughscriptNonce, which also fixes the object form; - in dev, the head tags the handler injects (the style patch and Vite client scripts, the collected styles, and a
csp-noncemeta for the styles the Vite client injects); - authored entries, as
context.nonce.
I have a PR ready and will link it here.
- 主要語言
- TypeScript
- 星號
- 522
- 分支
- 73
- 平均合併
- 1 天 4 小時
- 30 天內合併 PR
- 35
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 沒有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
solidjs/solid-vite-plugin 的其他 Issue
-
Test environment detection doesn't consider Vitest workspaces可能已有人在做 @carloitaben 於 56 天前認領。 未關閉1.x
難度 2/5 1-3 小時 新手友好度 78/100
solidjs/solid-vite-plugin#205 · 1 則留言 · 2 個 reaction ·
維護者通常 1 天內回覆
-
難度 3/5 1-2 天 新手友好度 58/100
solidjs/solid-vite-plugin#428 ·
維護者通常 1 天內回覆
-
難度 3/5 1-2 天 新手友好度 58/100
solidjs/solid-vite-plugin#427 ·
維護者通常 1 天內回覆
-
Dev: a stylesheet shared by the entry and a lazy component moves after the lazy component's styles未關閉
難度 3/5 半天 新手友好度 62/100
solidjs/solid-vite-plugin#425 ·
維護者通常 1 天內回覆
-
[3.0.0-next.50 / next] SSR build: the $$moduleUrl export added to a Worker main module stops workerd from starting可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 3/5 半天 新手友好度 55/100
solidjs/solid-vite-plugin#420 ·
維護者通常 1 天內回覆
查看 solidjs/solid-vite-plugin 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
-
bug
難度 2/5 1-3 小時 新手友好度 68/100
jbacalso24/mimry#459 · 1 則留言 ·
維護者通常 1 天內回覆
-
architecture help wanted hive/claimed-by-architect origin/architect stage/030-pr-in-progress tech-debt
難度 2/5 1-3 小時 新手友好度 78/100
kubestellar/console#24422 · 1 則留言 ·
維護者通常 1 天內回覆
-
area: backends type: docs
難度 1/5 1-3 小時 新手友好度 83/100
schlessera/brain-kit#2383 ·
維護者通常 1 天內回覆
-
agent duplicate providers tool triaged
難度 2/5 1-3 小時 新手友好度 74/100
維護者通常 1 天內回覆