fix(studio): allow github.com and vercel.com avatars in img-src CSP (#47885)

The TanStack build renders remote images as plain `<img>` tags — there's
no Next.js image optimizer rewriting them to same-origin `/_next/image`
URLs — so remote avatar origins now hit the CSP directly and were being
blocked (e.g. `Loading the image
'https://github.com/alaister.png?size=96' violates the following Content
Security Policy directive: "img-src 'self' ..."`).

**Changed:**
- Added `https://github.com` to `img-src` — GitHub profile avatars
(`https://github.com/<username>.png`, used by the user dropdown, AI
assistant messages, org invites, and audit logs). The URL 302s to
`avatars.githubusercontent.com`, which is already allowed (CSP validates
both hops of a redirect).
- Moved `https://vercel.com` from the dev/staging-only `img-src` list to
the unconditional list — Vercel integration account avatars
(`https://vercel.com/api/www/avatar/...`) load in prod too.

Audited all other `next/image` usages in studio: everything else is
either a local `${BASE_PATH}/img/...` asset (`'self'`) or a marketplace
image served from `NEXT_PUBLIC_MARKETPLACE_API_URL`, which is already in
`img-src`. The old `remotePatterns` entry for `api-frameworks.vercel.sh`
has no remaining references, so it was deliberately not ported.

## To test

- On the TanStack build, sign in with a GitHub-linked account and check
the user avatar renders in the top-right user dropdown (no CSP violation
in the console)
- Check org audit logs (`/org/_/audit`) render member avatars
- With a Vercel integration installed, check the account avatar renders
in org integration settings
- Sanity-check the Next.js build still renders the same avatars (both
builds share `getCSP()`)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * GitHub profile avatar images now display correctly.
* Image loading rules for staging and development environments were
refined to improve content security.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
This commit is contained in:
Alaister YoungandAlaister Young authored and GitHub committed 2026-07-13 22:20:12 +08:00
1 parent 20cb05230b
commit 67b17c885c
1 file changed
+10 -3
+10 -3
View File
@@ -58,6 +58,7 @@ const STRIPE_NETWORK_URL = 'https://*.stripe.network'
const CLOUDFLARE_URL = 'https://www.cloudflare.com'
const VERCEL_URL = 'https://vercel.com'
const VERCEL_INSIGHTS_URL = 'https://*.vercel-insights.com'
const GITHUB_URL = 'https://github.com'
const GITHUB_API_URL = 'https://api.github.com'
const GITHUB_USER_CONTENT_URL = 'https://raw.githubusercontent.com'
const GITHUB_USER_AVATAR_URL = 'https://avatars.githubusercontent.com'
@@ -125,12 +126,20 @@ export function getCSP() {
STAPE_URL,
...(isDevOrStaging ? [POSTHOG_URL] : []),
]
// The TanStack build renders remote images as plain <img> tags (no image
// optimizer proxy), so every remote image origin must be listed here
// explicitly — unlike the Next.js build, where the optimizer serves them
// from same-origin /_next/image URLs covered by 'self'.
const IMG_SRC_URLS = [
SUPABASE_URL,
SUPABASE_COM_URL,
SUPABASE_PROJECTS_URL,
// GitHub profile avatars, e.g. https://github.com/<username>.png
GITHUB_URL,
GITHUB_USER_AVATAR_URL,
GOOGLE_USER_AVATAR_URL,
// Vercel integration account avatars (https://vercel.com/api/www/avatar/...)
VERCEL_URL,
SUPABASE_ASSETS_URL,
USERCENTRICS_APP_URL,
STAPE_URL,
@@ -164,9 +173,7 @@ export function getCSP() {
`blob:`,
`data:`,
...IMG_SRC_URLS,
...(isDevOrStaging
? [SUPABASE_STAGING_PROJECTS_URL, NIMBUS_STAGING_PROJECTS_URL, VERCEL_URL]
: []),
...(isDevOrStaging ? [SUPABASE_STAGING_PROJECTS_URL, NIMBUS_STAGING_PROJECTS_URL] : []),
].join(' ')
const scriptSrcDirective = [