bug: image src attributes not validated for javascript: protocol URLs
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- javascript, react
Research direction
Inspect the image URL handling in packages/web/src/components/search/SearchBox.js, packages/web/src/components/basic/SelectedFilters.js, and packages/web/src/components/search/AIAnswer/Chat.js, starting with the listed lines and existing xss() usage. Confirm the affected image src values reject javascript: and other non-http(s) URLs while preserving valid URLs, and add or update coverage if the surrounding files provide tests.
Written by the indexing model from the issue text.
Description
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
- Dominant language
- JavaScript
- Stars
- 4.9k
- Forks
- 480
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from appbaseio/reactivesearch
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
appbaseio/reactivesearch#2322 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
appbaseio/reactivesearch#2321 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
appbaseio/reactivesearch#2319 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
appbaseio/reactivesearch#2324 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
appbaseio/reactivesearch#2323 ·
All issues in appbaseio/reactivesearch
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
keyxmakerx/Chronicle#967 ·
Maintainers usually reply within 1 day
-
good first issue hacktoberfest
Difficulty 1/5 Under an hour Newbie friendliness 92/100
RogueAlg0/taken#386 · 3 comments ·
Maintainers usually reply within 1 day
-
external-issue to-triage
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
LearningCircuit/local-deep-research#7067 ·
Maintainers usually reply within 1 day