Problem
Image src attributes in SearchBox, SelectedFilters, and AIAnswer Chat pass URLs through xss(), which only strips HTML tags but does NOT validate against javascript: protocol URLs. This means an attacker-provided image URL like javascript:alert('XSS') would bypass the sanitizer.
// packages/web/src/components/search/SearchBox.js:1159
<img src={XSS(props.iconURL)} alt="search-icon" />
// packages/web/src/components/basic/SelectedFilters.js:144
<img width="30px" alt="thumbnail" src={imageValue} />
The xss library strips HTML/JS from strings, but <img src="javascript:..."> doesn't need HTML injection — the URL itself is the attack vector.
Locations
packages/web/src/components/search/SearchBox.js (L1159, L1774)
packages/web/src/components/basic/SelectedFilters.js (L144)
packages/web/src/components/search/AIAnswer/Chat.js (L79)
Suggested Fix
Wrap URL assignment with a protocol check:
function sanitizeImageUrl(url) {
if (!url) return null;
try {
const parsed = new URL(url);
if (parsed.protocol === 'http:' || parsed.protocol === 'https:') return url;
} catch (e) { /* invalid URL */ }
return null;
}
Severity
High — XSS via image URL injection
Problem
Image
srcattributes in SearchBox, SelectedFilters, and AIAnswer Chat pass URLs throughxss(), which only strips HTML tags but does NOT validate againstjavascript:protocol URLs. This means an attacker-provided image URL likejavascript:alert('XSS')would bypass the sanitizer.The
xsslibrary strips HTML/JS from strings, but<img src="javascript:...">doesn't need HTML injection — the URL itself is the attack vector.Locations
packages/web/src/components/search/SearchBox.js(L1159, L1774)packages/web/src/components/basic/SelectedFilters.js(L144)packages/web/src/components/search/AIAnswer/Chat.js(L79)Suggested Fix
Wrap URL assignment with a protocol check:
Severity
High — XSS via image URL injection