Design Decision: Raw HTML Allowed

This component intentionally allows raw HTML injection in rendering callbacks to give developers full control over content display. This is a conscious design choice, not a bug. If you display user-generated content, you must sanitize it yourself.

Overview

The MultiSelect component uses innerHTML for rendering custom content in several callbacks. This provides maximum flexibility for creating rich, interactive content but requires developers to be aware of XSS (Cross-Site Scripting) implications when displaying untrusted data.

Callbacks Allowing HTML Injection

The following callbacks output is rendered using innerHTML and will execute any HTML/JavaScript:

CallbackUsed InRisk
renderOptionContentCallbackDropdown optionsHTML Injection
renderBadgeContentCallbackSelected item badgesHTML Injection
renderSelectedItemContentCallbackSelected items popoverHTML Injection
renderGroupLabelContentCallbackGroup headersHTML Injection
getIconCallbackOption iconsHTML Injection
getSubtitleCallbackOption subtitlesHTML Injection
getDisplayValueCallbackOption titles, badge textHTML Injection
getBadgeDisplayCallbackBadge textHTML Injection
getCounterCallbackCount badgesHTML Injection
getBadgeTooltipCallbackBadge tooltipsHTML if HTMLElement
customStylesCallbackStyle tag injectionCSS Injection

Safe Callbacks

The following callbacks are safe - their output is escaped or used as data only:

CallbackUsageStatus
getValueCallbackData lookup (ID extraction)Safe
getSearchValueCallbackSearch filteringSafe
getGroupCallbackGroup name extractionSafe
getDisabledCallbackBoolean checkSafe
getBadgeClassCallbackCSS class names onlySafe
getSelectedItemClassCallbackCSS class names onlySafe
beforeSearchCallbackSearch term transformationSafe
searchCallbackReturns data arraySafe
addNewCallbackReturns item objectSafe
selectCallbackEvent handlerSafe
deselectCallbackEvent handlerSafe
changeCallbackEvent handlerSafe
getRemoveButtonTooltipCallbackTitle attribute (escaped)Safe
getValueFormatCallbackForm value formattingSafe

Why Allow Raw HTML?

Benefits

  • Full control over rendering
  • Rich content with images, icons, badges
  • Complex layouts (flexbox, grid)
  • Custom styling per item
  • Interactive elements in options
  • No limitations on creativity

Your Responsibility

  • Sanitize user-generated content
  • Validate data from external APIs
  • Use a sanitization library (DOMPurify, sanitize-html)
  • Escape special characters when needed
  • Review third-party data sources

Sanitization Examples

Using DOMPurify

Sanitizing with DOMPurify
 

Simple Text Escaping

Simple HTML Escaping
 

Safe Static Content

Trusted Data (No Sanitization)
 

When to Sanitize

Data SourceSanitization Required?Example
Your own database (controlled)Usually NoProduct catalog, predefined options
User input (forms, comments)Yes - AlwaysUser names, descriptions, tags
External APIsYes - RecommendedGitHub users, third-party data
URL parametersYes - AlwaysSearch queries, filters from URL
Static hardcoded valuesNoCountry list, status options

Key Takeaways

  • This is intentional: Raw HTML support is a feature, not a vulnerability
  • You control the data: Only you know if your data is trusted
  • Sanitize at the boundary: Clean data before it enters rendering callbacks
  • Use established libraries: DOMPurify, sanitize-html, or your framework's built-in sanitizer
  • When in doubt, sanitize: It's better to over-sanitize than to expose an XSS vulnerability