Conversation
| const InnerAvatar = ({ for: author }: { for: Partial<IAccount> }) => ( | ||
| <> | ||
| {author.avatarUrl ? ( | ||
| {author.avatarUrl && author.avatarUrl.includes('githubusercontent.com') ? ( |
Check failure
Code scanning / CodeQL
Incomplete URL substring sanitization High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the issue, the code must reliably verify that the image avatar URL is actually hosted on a trusted domain (githubusercontent.com). Instead of performing a substring check on the entire URL (which could match on path/query, not just the host), we should parse the URL and compare its host property. The best approach is to use the built-in URL constructor (safe in recent browsers and Node.js) to extract the host/domain, and then explicitly check for exact matches or valid subdomains.
Modify line 12 in webviews/components/user.tsx:
- Parse
author.avatarUrlusing theURLconstructor. - Check if the hostname is exactly
githubusercontent.comor ends with.githubusercontent.com(to allow subdomains, if intended). - Only show the avatar image if this stricter check passes.
No external dependencies are needed.
| @@ -9,7 +9,20 @@ | ||
|
|
||
| const InnerAvatar = ({ for: author }: { for: Partial<IAccount> }) => ( | ||
| <> | ||
| {author.avatarUrl && author.avatarUrl.includes('githubusercontent.com') ? ( | ||
| {author.avatarUrl && (() => { | ||
| try { | ||
| const host = new URL(author.avatarUrl).hostname; | ||
| // Only allow githubusercontent.com or its subdomains | ||
| if (host === 'githubusercontent.com' || host.endsWith('.githubusercontent.com')) { | ||
| return ( | ||
| <img className="avatar" src={author.avatarUrl} alt="" role="presentation" aria-hidden="true"/> | ||
| ); | ||
| } | ||
| } catch { | ||
| // Malformed URL: fallback to icon | ||
| } | ||
| return null; | ||
| })() ? ( | ||
| <img className="avatar" src={author.avatarUrl} alt="" role="presentation" aria-hidden="true"/> | ||
| ) : ( | ||
| <Icon className="avatar-icon" src={require('../../resources/icons/dark/github.svg')} /> |
Fixes #8152