-
Notifications
You must be signed in to change notification settings - Fork 20
fix: validate identity.url scheme before rendering as external link #644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -282,6 +282,37 @@ export const isImageUrl = (url: string): boolean => { | |
| return /\.(jpg|jpeg|png|gif|webp)$/i.test(url); | ||
| }; | ||
|
|
||
| /** | ||
| * Sanitize a user-supplied URL for use as an external `<a href>`. | ||
| * | ||
| * Auto-prefixes `https://` when the input has no scheme (so values like | ||
| * `evil.com/path` aren't treated as relative links), then validates that the | ||
| * resulting URL parses and uses an `http:` or `https:` protocol. Anything | ||
| * else (e.g. `javascript:`, `data:`, malformed input) is rejected. | ||
| * | ||
| * @param url - The user-supplied URL. | ||
| * @returns The sanitized absolute URL, or `null` if it is unsafe / invalid. | ||
| */ | ||
| export const sanitizeExternalUrl = ( | ||
| url: string | null | undefined | ||
| ): string | null => { | ||
| if (!url) return null; | ||
| const trimmed = url.trim(); | ||
| if (!trimmed) return null; | ||
| const withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed) | ||
| ? trimmed | ||
| : `https://${trimmed}`; | ||
| try { | ||
| const parsed = new URL(withScheme); | ||
| if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { | ||
| return null; | ||
| } | ||
| return parsed.toString(); | ||
| } catch { | ||
| return null; | ||
| } | ||
| }; | ||
|
Comment on lines
+296
to
+314
|
||
|
|
||
| /** | ||
| * Shorten an Ethereum address for display. | ||
| * @param address - The address to shorten. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sanitizeExternalUrlcurrently prependshttps://for any input without a detected scheme, but this produces incorrect results for protocol-relative URLs like//example.com/path(it becomeshttps:////example.com/path, which parses with an empty host and doesn’t reliably become an external link). Handle the//...case explicitly (e.g., prefix withhttps:) and consider rejecting other relative-leading inputs (like/...,#...,?...) or requiringparsed.hostnameto be non-empty to ensure the result is truly an absolute external URL.