fix(sanitization): match onload case- and space-insensitively - #31417
Conversation
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 is attempting to deploy a commit to the Ionic Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Hey @chuhuangvio-itch! Thanks for catching this, the fix looks right and we're going to merge it. For next time, we do have a security policy with a private reporting channel, it's just inherited from the org so it shows up on our Security tab rather than as a I pushed a commit onto your branch with a few changes. The test payloads are nested now ( Edit: This fix has been released in v9.0.2! |
What is the current behavior?
sanitizeDOMString(core/src/utils/sanitization/index.ts) blocks untrusted HTML containingonload=before it reachesinnerHTML, becauseonloadcan 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 missesonLoad=,ONLOAD=, oronload =(whitespace before=) even though HTML parses all of those as the same event handler.What is the new behavior?
=(/onload\s*=/i), matching how HTML actually parses attribute names.Does this introduce a breaking change?
Other information
sanitizeDOMStringis used byion-toast,ion-loading, theion-alertmessage,ion-refresher-content, andion-infinite-scroll-contentto 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 reachinnerHTMLunfiltered.I didn't find an existing
SECURITY.mdor 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.