mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(all): add ability to eject from Ionic sanitizer (#20457)
resolves #18277
This commit is contained in:
@@ -175,6 +175,11 @@ export interface IonicConfig {
|
||||
*/
|
||||
experimentalTransitionShadow?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, Ionic will enable a basic DOM sanitizer on component properties that accept custom HTML.
|
||||
*/
|
||||
sanitizerEnabled?: boolean;
|
||||
|
||||
// PRIVATE configs
|
||||
keyboardHeight?: number;
|
||||
inputShims?: boolean;
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
* in an untrusted string
|
||||
*/
|
||||
|
||||
export const sanitizeDOMString = (untrustedString: string | undefined): string | undefined => {
|
||||
export const sanitizeDOMString = (untrustedString: IonicSafeString | string | undefined): string | undefined => {
|
||||
try {
|
||||
if (typeof untrustedString !== 'string' || untrustedString === '') { return untrustedString; }
|
||||
if (untrustedString instanceof IonicSafeString) { return untrustedString.value; }
|
||||
if (!isSanitizerEnabled() || typeof untrustedString !== 'string' || untrustedString === '') { return untrustedString; }
|
||||
|
||||
/**
|
||||
* Create a document fragment
|
||||
@@ -122,5 +123,22 @@ const getElementChildren = (el: any) => {
|
||||
return (el.children != null) ? el.children : el.childNodes;
|
||||
};
|
||||
|
||||
const isSanitizerEnabled = (): boolean => {
|
||||
const win = window as any;
|
||||
const config = win && win.Ionic && win.Ionic.config;
|
||||
if (config) {
|
||||
if (config.get) {
|
||||
return config.get('sanitizerEnabled', true);
|
||||
} else {
|
||||
return config.sanitizerEnabled === true || config.sanitizerEnabled === undefined;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const allowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
|
||||
const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
|
||||
|
||||
export class IonicSafeString {
|
||||
constructor(public value: string) {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { sanitizeDOMString } from "..";
|
||||
import { IonicSafeString, sanitizeDOMString } from "..";
|
||||
|
||||
describe('sanitizeDOMString', () => {
|
||||
it('disable sanitizer', () => {
|
||||
enableSanitizer(false);
|
||||
expect(sanitizeDOMString('<img src="x" onerror="alert(document.cookie);">'))
|
||||
.toEqual('<img src="x" onerror="alert(document.cookie);">');
|
||||
})
|
||||
|
||||
it('bypass sanitizer', () => {
|
||||
expect(sanitizeDOMString(new IonicSafeString('<img src="x" onerror="alert(document.cookie);">')))
|
||||
.toEqual('<img src="x" onerror="alert(document.cookie);">');
|
||||
});
|
||||
|
||||
it('filter onerror', () => {
|
||||
expect(sanitizeDOMString('<img src="x" onerror="alert(document.cookie);">'))
|
||||
@@ -41,4 +51,10 @@ describe('sanitizeDOMString', () => {
|
||||
expect(sanitizeDOMString('<ion-item><ion-label>Hello!</ion-label><ion-button onclick="alert(document.cookie);">Click me</ion-button>'))
|
||||
.toEqual('<ion-item><ion-label>Hello!</ion-label><ion-button>Click me</ion-button></ion-item>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const enableSanitizer = (enable: boolean = true) => {
|
||||
window.Ionic = {};
|
||||
window.Ionic.config = {};
|
||||
window.Ionic.config.sanitizerEnabled = enable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user