Skip to content

fix(sanitization): match onload case- and space-insensitively - #31417

Open
chuhuangvio-itch wants to merge 1 commit into
ionic-team:mainfrom
chuhuangvio-itch:fix/sanitize-dom-string-onload-case-bypass
Open

fix(sanitization): match onload case- and space-insensitively#31417
chuhuangvio-itch wants to merge 1 commit into
ionic-team:mainfrom
chuhuangvio-itch:fix/sanitize-dom-string-onload-case-bypass

Conversation

@chuhuangvio-itch

Copy link
Copy Markdown

What is the current behavior?

sanitizeDOMString (core/src/utils/sanitization/index.ts) blocks untrusted HTML containing onload= before it reaches innerHTML, because onload can fire synchronously while the string is being parsed into the working document fragment — before the later attribute-allowlist pass runs. The check is a plain lowercase substring match (untrustedString.includes('onload=')), so it misses onLoad=, ONLOAD=, or onload = (whitespace before =) even though HTML parses all of those as the same event handler.

What is the new behavior?

  • Replaced the substring check with a case-insensitive regex that also tolerates whitespace around = (/onload\s*=/i), matching how HTML actually parses attribute names.
  • Added a test covering the case and whitespace variants.

Does this introduce a breaking change?

  • Yes
  • No

Other information

sanitizeDOMString is used by ion-toast, ion-loading, the ion-alert message, ion-refresher-content, and ion-infinite-scroll-content to sanitize developer-supplied HTML strings that may embed end-user input (e.g. another user's display name rendered in a toast/alert). This closes a gap where a payload like <svg onLoad=...> could bypass the intended guard and reach innerHTML unfiltered.

I didn't find an existing SECURITY.md or private vulnerability reporting channel enabled on this repo, so opening this directly as a PR with the fix rather than filing a separate public issue describing the bypass.

sanitizeDOMString blocked untrusted HTML that contains "onload="
before setting it via innerHTML, because onload can fire
synchronously while parsing into the detached document fragment,
ahead of the later attribute-allowlist pass.

The check used a plain lowercase substring match, so variants like
onLoad=, ONLOAD= or onload = (whitespace before the =) were not
caught, even though HTML parses them as the same event handler.
Use a case-insensitive regex that also tolerates whitespace around
the =.

Adds a test covering the case and whitespace variants.
@chuhuangvio-itch
chuhuangvio-itch requested a review from a team as a code owner September 1, 2026 14:30
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

@chuhuangvio-itch is attempting to deploy a commit to the Ionic Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the package: core @ionic/core package label Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant