Skip to content

fix(server): sandbox user-provided SVGs - #5916

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/secure-svg-rendering
Aug 9, 2026
Merged

fix(server): sandbox user-provided SVGs#5916
t3dotgg merged 1 commit into
mainfrom
t3code/secure-svg-rendering

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Aug 9, 2026

Copy link
Copy Markdown
Member

User-provided SVGs are served from signed URLs on the app origin. Opening one directly could run active SVG content with access to that origin.

This adds a restrictive Content Security Policy to SVG asset responses. Inline SVG styles still render, while scripts, external loads, and same-origin access are blocked. Raster asset responses are unchanged.

Tests: vp test run apps/server/src/http.test.ts

Made with GPT-5.6 using the Codex harness in T3 Code.


Note

Medium Risk
Targets a real XSS/origin-abuse vector on user content, but the change is limited to response headers on the asset route and is covered by unit tests.

Overview
User-uploaded SVGs served from signed asset URLs now get a restrictive Content-Security-Policy so opening them directly cannot run scripts or access the app origin.

A shared assetResponseHeaders helper centralizes asset response headers: .svg paths (case-insensitive) add default-src 'none'; style-src 'unsafe-inline'; sandbox on top of existing private cache and nosniff. Raster and other assets keep the same headers as before, with no CSP.

The signed asset GET route uses this helper instead of inline header objects. Tests cover SVG vs PNG behavior.

Reviewed by Cursor Bugbot for commit 457efa6. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add CSP sandbox header to SVG assets served by the asset route

Adds a Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; sandbox header to responses for .svg files (case-insensitive) to prevent script execution in user-provided SVGs. Header logic is centralized in a new exported assetResponseHeaders function in http.ts. Non-SVG assets continue to receive only Cache-Control and X-Content-Type-Options headers.

Macroscope summarized 457efa6.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 31e48ec0-68e5-4c41-88ce-83bb7b77ebc4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 11.3 KiB 11.3 KiB +4 B (+0.0%) 15.1 KiB
Codex Thread snapshot wire 5.5 KiB 5.5 KiB −8 B (−0.1%) 7.3 KiB
Codex Live turn WebSocket wire 5.9 KiB 5.9 KiB +12 B (+0.2%) 7.8 KiB
Codex Live turn WebSocket decoded 49.7 KiB 49.7 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 16 16 0 (0.0%) 21
Claude Total thread wire 11.3 KiB 11.3 KiB +9 B (+0.1%) 15.1 KiB
Claude Thread snapshot wire 5.5 KiB 5.5 KiB +4 B (+0.1%) 7.3 KiB
Claude Live turn WebSocket wire 5.8 KiB 5.9 KiB +5 B (+0.1%) 7.8 KiB
Claude Live turn WebSocket decoded 50.6 KiB 50.6 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 16 16 0 (0.0%) 21

Baseline: 0d38866 · PR result: 457efa6 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 94.6 KiB
  • Claude decoded thread snapshot: 95.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 457efa6

This PR adds standard security hardening by sandboxing user-provided SVG files with restrictive CSP headers to prevent XSS attacks. The change is small, well-tested, and follows established security best practices for handling untrusted SVG content.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg
t3dotgg merged commit 2abe668 into main Aug 9, 2026
17 checks passed
@t3dotgg
t3dotgg deleted the t3code/secure-svg-rendering branch August 9, 2026 23:51
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Aug 10, 2026
## What's Changed
* fix(web): thread title button no longer eats the drag area by @nathangerday in pingdotgg/t3code#5857
* fix(web): unify usage page chrome by @t3-code[bot] in pingdotgg/t3code#5823
* fix(shell): add ~/.local/bin to the Windows CLI resolver so native-installed providers are found by @arhxam in pingdotgg/t3code#5074
* fix(web): match settings search shortcut styling to command palette's by @UtkarshUsername in pingdotgg/t3code#5841
* fix(mobile): long-pressing a thread row no longer navigates into the thread by @juliusmarminge in pingdotgg/t3code#5901
* fix(server): usage no longer double-counts forked Codex sessions by @t3dotgg in pingdotgg/t3code#5887
* fix(server): sandbox user-provided SVGs by @t3dotgg in pingdotgg/t3code#5916
* fix(web): match usage titlebar text styling by @t3-code[bot] in pingdotgg/t3code#5897

## New Contributors
* @nathangerday made their first contribution in pingdotgg/t3code#5857

**Full Changelog**: pingdotgg/t3code@v0.0.33-nightly.20260809.1047...v0.0.33-nightly.20260810.1054

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.33-nightly.20260810.1054
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). 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.

1 participant