Skip to content

fix(server): HTML renders and PDFs load behind a proxy that forbids framing - #28

Merged
Andrey170170 merged 113 commits into
dev_vmfrom
fix/frameable-asset-documents
Oct 9, 2026
Merged

Andrey170170 merged 113 commits into
dev_vmfrom
fix/frameable-asset-documents

Conversation

@Andrey170170

Copy link
Copy Markdown
Owner

Summary

A client on one host (dev.…) frames asset documents served by the environment on another (code.…). The gateway in front of the environment adds X-Frame-Options: SAMEORIGIN, so every in-thread HTML render and PDF preview came up blank. Browsers ignore X-Frame-Options when the response names its own frame-ancestors, so the server now does.

 GET /api/assets/<signed token>/<file>   (inline, not download)
   text/html, *.html, *.htm
-    Content-Security-Policy: sandbox allow-scripts allow-forms allow-popups
+    Content-Security-Policy: sandbox allow-scripts allow-forms allow-popups; frame-ancestors *
   application/pdf, *.pdf
-    (no Content-Security-Policy)
+    Content-Security-Policy: frame-ancestors *

Downloads, SVGs, media and the app shell are unchanged.

Evidence

  • Before: curl -I https://code.andrei-homelab.com/ shows x-frame-options: SAMEORIGIN from nginx and no frame-ancestors on asset documents, so the cross-origin frame is refused.
    After: vp test run apps/server/src/http.test.ts passes (28 tests), asserting the new header on HTML by mime type, HTML by path, PDF by mime type and PDF by path.
  • Not yet checked in a browser against the real gateway; that happens after the Forgejo release is installed.

Merge Danger

Door: two-way

Reverting the commit restores the old headers; nothing is persisted.

Blast Radius: small

Asset documents had no framing restriction from the server before, so this only matters where a proxy imposed one. Those documents can now be framed by any site that holds the signed, expiring URL; HTML stays sandboxed to an opaque origin.

Claude Opus 5.5 (1M context) via Claude Code in T3 Code

🤖 Generated with Claude Code

t3dotgg and others added 30 commits October 5, 2026 21:02
… group (pingdotgg#16353)

Fixes pingdotgg#4880. Originally pingdotgg#14639 by @Project516.

Co-authored-by: Project516 <138796702+Project516@users.noreply.github.com>
…ingdotgg#13758)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…14718)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…16357)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…dotgg#16206)

Favicons in ProjectEnrichmentService now keep for 15 minutes. Repository identity keeps its 1-minute TTL, so remote changes still show within a minute.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… histories (pingdotgg#16358)

The Claude capabilities probe now asks for usage with skipBehaviors, so it no longer scans every local transcript and misses its 4 s deadline. Takes over pingdotgg#14456.

Co-authored-by: Ashkaan <a@ashkaan.me>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tgg#16285)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…otgg#16223)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16207)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16315)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…gain (pingdotgg#16363)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16314)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g#16253)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16382)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
juliusmarminge and others added 23 commits October 6, 2026 20:30
…g#9786)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#9788)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#10298)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…rver (pingdotgg#16718)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g#16741)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…16752)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ngdotgg#16290)

Co-authored-by: spoukyii <61633921+spoukyii@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ices (pingdotgg#16631)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tgg#16762)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s of untracked files (pingdotgg#16771)

Co-authored-by: Braulio Oliveira <brauliobo@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…eep (pingdotgg#16760)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16761)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16782)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in 109 upstream commits (GitHub API transport, MCP OAuth for outside
agents, split auth scopes, server-side preview browser, status polling fixes).

Fork adjustments:
- Side-chat RPCs keep their orchestration scopes beside upstream's split
  scopes and are listed in the new RPC instrumentation table; their handlers
  drop the removed observeRpc* wrappers.
- Side-chat composer passes the new canOperateThread prop.
- The SQLite client binds booleans as 0/1: upstream's pairing query binds a
  boolean, which Node 24.16 (the service runtime) rejects.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Upstream now pins overrides such as undici@^8 to the catalog; the packaging
script looked up the whole selector and failed. Mirrors upstream pingdotgg#16411.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…raming

Clients frame asset documents from the environment's origin, which is
often not their own. A reverse proxy that adds X-Frame-Options: SAMEORIGIN
blanked every HTML render and PDF preview in that setup. Inline HTML and
PDF asset responses now carry `frame-ancestors *`, which browsers honour
in place of X-Frame-Options.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T00:05:27.875812Z 0a35443 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Oct 8, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9df3ee01cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/server/src/http.ts Outdated
// Clients frame documents from another origin than the environment's, so name
// the allowed ancestors here: a browser that sees `frame-ancestors` ignores any
// `X-Frame-Options` a reverse proxy adds. The signed URL is the access control.
const FRAMEABLE_CONTENT_SECURITY_POLICY = "frame-ancestors *";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allow the desktop schemes as frame ancestors

In the desktop client, the parent document uses the custom t3code://app or t3code-dev://app origin, while signed asset URLs are resolved against the environment's HTTP base URL. CSP's * source matches HTTP(S) ancestors or ancestors using the protected resource's scheme, so it does not match either desktop scheme. Consequently, this newly enforced policy blocks every HTML and PDF iframe in desktop, even without a reverse proxy; include the two desktop schemes explicitly in the frame-ancestors list.

AGENTS.md reference: AGENTS.md:L23-L31

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Real: CSP's * does not match the desktop renderer's custom-scheme origins, so this would have blanked HTML and PDF frames in desktop. Fixed in 0a35443 by listing t3code://app and t3code-dev://app alongside *.

CSP's `*` matches only http(s) ancestors, so the desktop app's custom
scheme origins are listed explicitly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Andrey170170
Andrey170170 merged commit b4bdb5e into dev_vm Oct 9, 2026
8 of 9 checks passed
@Andrey170170
Andrey170170 deleted the fix/frameable-asset-documents branch October 9, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.