Description
Several card components in src/components/cards/ render content from src/data/ registry entries using dangerouslySetInnerHTML. If a registry entry (contributed via PR) contains a <script> tag or an event handler attribute such as onerror, the browser executes the injected script in the context of the page.
Steps to Reproduce
- Add an activity entry in
src/data/activities/ with a description field containing:
"<img src=x onerror=alert(document.cookie)>".
- Open the Activities page.
- Observe the alert fires, confirming XSS.
Root Cause
dangerouslySetInnerHTML={{ __html: activity.description }} is used without first sanitizing the HTML string through a library like DOMPurify.
Impact
Stored XSS via the data registry. Any PR that modifies data files could inject malicious scripts executed for all site visitors.
Proposed Fix
import DOMPurify from "dompurify";
<div
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(activity.description),
}}
/>
Install: npm install dompurify @types/dompurify
Description
Several card components in
src/components/cards/render content fromsrc/data/registry entries usingdangerouslySetInnerHTML. If a registry entry (contributed via PR) contains a<script>tag or an event handler attribute such asonerror, the browser executes the injected script in the context of the page.Steps to Reproduce
src/data/activities/with adescriptionfield containing:"<img src=x onerror=alert(document.cookie)>".Root Cause
dangerouslySetInnerHTML={{ __html: activity.description }}is used without first sanitizing the HTML string through a library like DOMPurify.Impact
Stored XSS via the data registry. Any PR that modifies data files could inject malicious scripts executed for all site visitors.
Proposed Fix
Install:
npm install dompurify @types/dompurify