Move asciicast renderer to iframe by silverwind · Pull Request #37285 · go-gitea/gitea · GitHub
Skip to content

Move asciicast renderer to iframe#37285

Draft
silverwind wants to merge 10 commits intogo-gitea:mainfrom
silverwind:cast
Draft

Move asciicast renderer to iframe#37285
silverwind wants to merge 10 commits intogo-gitea:mainfrom
silverwind:cast

Conversation

@silverwind
Copy link
Copy Markdown
Member

@silverwind silverwind commented Apr 19, 2026

Fixes #37257.

  • asciicast now renders via the frontend iframe pattern (same as 3D, OpenAPI)
  • new ExternalRendererOptions.SrcMethod="src" loads the iframe via iframe.src so it uses its own response CSP instead of inheriting the parent's (per CSP3 §4.2.3.6, srcdoc iframes inherit)
  • new AdditionalCSPSources map[string][]string appends per-directive sources; asciicast adds 'wasm-unsafe-eval' to script-src
  • main site CSP unchanged
  • RenderFile rejects SrcMethod="src" without a safe sandbox (empty or allow-same-origin)
  • old custom asciicast renderer + CSS + JS deleted
  • e2e asserts the cast's rendered text appears (only true if WASM executed)

This PR was written with the help of Claude Opus 4.7

asciinema-player uses WebAssembly, which is blocked by the main site
CSP introduced in go-gitea#37232 (script-src lacks 'wasm-unsafe-eval'). Moving
the renderer into an iframe does not help on its own because srcdoc
iframes inherit the parent CSP per CSP3 §4.2.3.6.

Two changes:
- add 'wasm-unsafe-eval' to script-src so srcdoc iframes can load WASM
- convert the asciicast renderer to the existing frontendRenderer
  iframe pattern (same as 3D viewer and openapi-swagger) for
  consistency and isolation

Fixes go-gitea#37257

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Apr 19, 2026
@silverwind silverwind marked this pull request as draft April 19, 2026 02:38
The asciinema-player's .ap-term div still needs overflow: hidden to fix
the scrollbar regression from go-gitea#26159. The rule is now scoped to the
iframe via a local CSS import in the plugin.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
@silverwind silverwind changed the title Fix CSP blocking WebAssembly in asciicast renderer Move asciicast renderer to iframe Apr 19, 2026
silverwind and others added 3 commits April 19, 2026 04:41
Reverts the main-site CSP change. Instead introduces
ExternalRendererOptions.SrcMethod ("src" | "srcdoc"/""):

- "srcdoc" (default, all other iframe renderers): iframe content is
  fetched by JS and set via srcdoc; the iframe document inherits the
  parent page's CSP per CSP3 §4.2.3.6.
- "src" (asciicast only): the parent page sets iframe.src and the
  iframe document uses the response's own CSP — which allows
  'wasm-unsafe-eval' for WebAssembly. Isolation is preserved by the
  iframe sandbox attribute; the main site CSP stays untouched.

The e2e test now asserts the cast's rendered "test" text appears
inside the player — that only happens if WASM actually loaded.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
- SrcMethod doc collapsed to 2 lines mentioning CSP
- Drop regression narration in e2e test and one-liner for asciicast registration
- Replace switch-with-no-variable in RenderFile with an if/else ladder;
  move the PDF-RENDER-SANDBOX note next to the branch it actually describes
- Fix a leftover typo in pdf test comment

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
@silverwind
Copy link
Copy Markdown
Member Author

silverwind commented Apr 19, 2026

@silverwind silverwind marked this pull request as ready for review April 19, 2026 16:29
silverwind and others added 3 commits April 19, 2026 18:29
Renderers declare per-directive source additions as a map instead of
hardcoding 'wasm-unsafe-eval' in the router. Only the asciicast renderer
sets {"script-src": {"'wasm-unsafe-eval'"}}; the main site CSP and
other iframe renderers are unaffected.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
* 'cast' of github.com:silverwind/gitea:
  Fix Mermaid diagrams failing when node labels contain line breaks (go-gitea#37296)
  Add project column picker to issue and pull request sidebar (go-gitea#37037)
  Fix container auth for public instance (go-gitea#37290)
  Refactor frontend `tw-justify-between` layouts to `flex-left-right` (go-gitea#37291)
  Update Nix flake (go-gitea#37284)
  Workflow Artifact Info Hover (go-gitea#37100)
@silverwind
Copy link
Copy Markdown
Member Author

Made it more flexible, now the asciicast renderer passes wasm-unsafe-eval, exactly what it needs.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses the .cast (asciicast) rendering CSP regression by moving asciicast rendering into the “frontend external renderer” iframe pipeline and allowing that iframe to be loaded via iframe.src with its own response-level CSP (including wasm-unsafe-eval).

Changes:

  • Replace the legacy backend asciicast renderer + in-page player init with a frontend external-render plugin (asciicast) that runs inside the external render iframe.
  • Add ExternalRendererOptions.SrcMethod + AdditionalCSPSources to support iframe.src loading and per-renderer CSP extensions.
  • Update iframe init logic and E2E coverage for iframe-based asciicast rendering.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
web_src/js/render/plugins/frontend-asciicast.ts New frontend-render plugin implementation for asciicast (uses opts.contentString() + wasm-enabled CSP path).
web_src/js/render/plugins/frontend-asciicast.css Removes old container sizing rules; keeps player UI regression fixes.
web_src/js/markup/render-iframe.ts Adds support for data-src-method="src" to load iframe content via iframe.src.
web_src/js/markup/content.ts Removes legacy asciicast in-markup initializer hook.
web_src/js/external-render-frontend.ts Registers the asciicast frontend plugin for external rendering.
web_src/css/repo.css Removes .asciicast padding override tied to the old non-iframe renderer.
web_src/css/index.css Drops import of the old asciicast markup CSS.
types.d.ts Expands asciinema-player.create() typing to support {data} / {url} variants.
tests/e2e/file-view-render.test.ts Updates asciicast E2E test to validate iframe-based rendering and content display.
routers/web/repo/render.go Adds buildIframeCSP and emits response CSP when iframe is loaded via src.
modules/markup/renderer.go Extends ExternalRendererOptions with SrcMethod + AdditionalCSPSources.
modules/markup/render_test.go Adds unit coverage for data-src-method="src" attribute output.
modules/markup/render.go Emits data-src-method="src" on iframes when requested by renderer options.
modules/markup/external/frontend.go Plumbs SrcMethod/CSP additions from frontendRenderer into renderer options.
modules/markup/external/external.go Registers asciicast as a frontend external renderer with wasm CSP relaxation.
modules/markup/asciicast/asciicast.go Removes the old backend asciicast renderer implementation.
main.go Removes the legacy asciicast renderer registration import.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/e2e/file-view-render.test.ts
Comment thread routers/web/repo/render.go Outdated
Comment thread modules/markup/renderer.go
…e non-ASCII test

- Reject SrcMethod="src" when the iframe sandbox is missing or contains
  allow-same-origin (panic in dev/testing, log + 500 in prod).
- buildIframeCSP now emits any directive in AdditionalCSPSources, not
  just the baseline ones; output sorted for deterministic tests.
- Restore the non-ASCII branch case in the asciicast e2e to guard the
  render-URL escaping path; still asserts WASM rendered the cast text.
- Unit test for iframeSandboxSafeForSrc covering safe/unsafe sandboxes.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
@wxiaoguang wxiaoguang marked this pull request as draft April 19, 2026 17:36
@wxiaoguang
Copy link
Copy Markdown
Contributor

Too many hacky patches, need to rewrite to a new approach.

@silverwind
Copy link
Copy Markdown
Member Author

silverwind commented Apr 19, 2026

Please do. My verdict: srcdoc iframe can not have a CSP distinct from the parent page, only a src iframe can. That is the root of the issue and the complexity. Claude also evaluated using src iframe everywhere but that also ran into other issues.

@wxiaoguang
Copy link
Copy Markdown
Contributor

It needs a complete design globally.

And, all "iframe renders" should share the same approach: only disallow "same-origin", allow all others, let them do anything they need. There shouldn't be so many "additional" options.

@silverwind
Copy link
Copy Markdown
Member Author

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

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSP bug: Missing 'wasm-unsafe-eval' or 'unsafe-eval' when opening .cast file

5 participants