diff --git a/core/src/utils/sanitization/index.ts b/core/src/utils/sanitization/index.ts
index bb851fea7e0..2ee633f4a6f 100644
--- a/core/src/utils/sanitization/index.ts
+++ b/core/src/utils/sanitization/index.ts
@@ -36,8 +36,12 @@ export const sanitizeDOMString = (untrustedString: IonicSafeString | string | un
* fragment in Chrome. If a string
* contains onload then we should not
* attempt to add this to the fragment.
+ *
+ * HTML attribute names are case-insensitive and may have whitespace
+ * around the `=`, so match those variants too (e.g. `onLoad=`,
+ * `ONLOAD =`) instead of only the exact lowercase `onload=` substring.
*/
- if (untrustedString.includes('onload=')) {
+ if (/onload\s*=/i.test(untrustedString)) {
return '';
}
diff --git a/core/src/utils/sanitization/test/sanitization.spec.ts b/core/src/utils/sanitization/test/sanitization.spec.ts
index 2ca069e387f..03c2abf7c48 100644
--- a/core/src/utils/sanitization/test/sanitization.spec.ts
+++ b/core/src/utils/sanitization/test/sanitization.spec.ts
@@ -26,6 +26,21 @@ describe('sanitizeDOMString', () => {
).toEqual('');
});
+ it('filter onload regardless of case or whitespace around =', () => {
+ /**
+ * onload is blocked with an upfront string check (rather than the
+ * attribute-stripping pass used for onerror/onclick above) because it
+ * can fire synchronously while the untrusted string is being parsed
+ * into the working document fragment, before that pass runs. HTML
+ * attribute names are case-insensitive and may have whitespace around
+ * `=`, so the check must not be a plain lowercase substring match.
+ */
+ expect(sanitizeDOMString('