fix: sanitize untrusted external metadata links#935
fix: sanitize untrusted external metadata links#935afurm wants to merge 2 commits intosolana-foundation:masterfrom
Conversation
|
@afurm is attempting to deploy a commit to the Solana Foundation Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR introduces a Confidence Score: 5/5Safe to merge — all remaining findings are P2 style suggestions that do not affect correctness or security. The security fix is correctly implemented: No files require special attention for merging; the P2 note on
|
| Filename | Overview |
|---|---|
| app/shared/lib/safe-external-url.ts | New URL-sanitizer utility; correctly validates protocol via new URL() allowlist; returns the trimmed input rather than url.href (intentional, minor) |
| app/shared/lib/tests/safe-external-url.spec.ts | Unit tests cover http/https acceptance, dangerous protocols (javascript:, data:, mailto:), relative paths, empty/undefined inputs, and the type-guard export |
| app/components/common/NFTArt.tsx | Replaces next/link with <a> and gates rendering behind getSafeExternalUrl; NFTs with native ipfs:// or ar:// URIs will silently lose the "VIEW ORIGINAL" link |
| app/components/account/TokenAccountSection.tsx | Adds URL sanitization for token website, bridge contract, asset contract, and NFT external URL; also fixes the bridged-asset-contract href bug |
| app/components/account/tests/TokenAccountSection.spec.tsx | Regression tests verify javascript: website is not rendered as a link, and the bridged-asset row uses the correct asset contract URL |
| app/components/account/VerifiedBuildCard.tsx | Adds URL sanitization for repository URL via getSafeExternalUrl inside the DisplayType.URL switch case |
| app/components/account/CompressedNftCard.tsx | Adds URL sanitization for external_url field; falls back to plain text with a - placeholder when the URL is unsafe or absent |
| app/components/account/ConfigAccountSection.tsx | Adds URL sanitization for validator website; unsafe values shown as plain text |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Untrusted external URL\nfrom metadata] --> B[getSafeExternalUrl]
B --> C{typeof value\n=== 'string'?}
C -- No --> D[return null]
C -- Yes --> E{trimmedValue\nempty?}
E -- Yes --> D
E -- No --> F[new URL parse]
F --> G{Parse\nsucceeds?}
G -- No --> D
G -- Yes --> H{protocol is\nhttp: or https:?}
H -- No --> D
H -- Yes --> I[return trimmedValue]
I --> J[Render as <a href=...>]
D --> K[Render as plain text]
Reviews (1): Last reviewed commit: "fix unsafe external links" | Re-trigger Greptile
Description
Sanitize untrusted external URLs before rendering them as clickable links in account and NFT views.
This change fixes a user-facing security issue where third-party metadata values such as token websites, NFT
external_url, token metadata URIs, compressed NFT links, validator config websites, and verified-build repository URLs could be rendered directly intohrefattributes. Unsafe or malformed values now render as plain text instead of clickable links.It also fixes a separate bug in the token mint overview where the "Bridged Asset Contract" row incorrectly linked to the bridge contract URL instead of the asset contract URL.
Type of change
Screenshots
N/A — no layout or visual design changes.
Testing
javascript:website values not rendering as clickable linkspnpm exec eslint app/shared/lib/safe-external-url.ts app/shared/lib/__tests__/safe-external-url.spec.ts app/components/account/__tests__/TokenAccountSection.spec.tsx app/components/account/TokenAccountSection.tsx app/components/account/CompressedNftCard.tsx app/components/account/ConfigAccountSection.tsx app/components/common/NFTArt.tsx app/components/account/VerifiedBuildCard.tsxpnpm exec vitest --project specs run app/shared/lib/__tests__/safe-external-url.spec.ts app/components/account/__tests__/TokenAccountSection.spec.tsxRelated Issues
No matching public issue found.
No overlapping open PR found for this fix in the fork or the upstream repository during triage.
Checklist
build:infoscript to update build informationAdditional Notes