The author of this post was reviewing a target that had an interactive playground for developers to write and evaulate Javascript to interact with a developer API. This is a great attack surface to target! Sometimes, the vulnerability is the attack surface.
The application attempts to sandbox the users JavaScript execution by creating a separate iframe and running the code in there. However, the iframe didn't contain the sandbox attribute, depsite being in a dive and having a name that contained sandbox in it. This means that the iframe is considered same origin and can access content within the parent page.
The iframe creation sets the src via data:text.... Normally, this would mean it has the null origin. Luckily for the author, the page calls document.open() and document.write() on the iframes document before the URI loads! This means that the iframe's origin is from the parent. In practice, this means that any code injected into the textarea is evaulated on the full origin of the target site. This creates DOM XSS but they needed a remote way to exploit it.
How do we get a user to add this payload? The author has many posts are weaponizing drag in drop across windows. When a user starts dragging an element on Page A, which then redirects to page B, the drag action persists across windows. To exploit this, an attacker can host a page with an attractive draggable image, set the drag data to be an XSS payload, redirect to the victim page and when the user releases the drag, it drops right into the code editor. This works on Firefox and Safari. On Chrome, it requires a popup instead of a redirect.
Even with the drag and drop exploit, the victim still needs to click Evalulate. Luckily for them, there's a postMessage handler that doesn't check the origin. So, any cross-origin window is able to call Evalulate on the editor. With this, they can achieve full XSS via some user interaction. The chain is a drag-n-drop switcheroo with an XSS payload onto the parent page that is triggered by a postMessage.
Full XSS wasn't enough; they wanted to get an account takeover. The website used OAuth for logging in. They prevented the OAuth callback from working server-side by using a cookie bomb to trigger a 431 error. Now, the auth code is UNUSED within the URL but the code wasn't used. Using this authorization code leads to a complete account takeover.
This is a crazy chain of bugs! It does require a drag-n-drop so the triager on the bug bounty program says that it requires too much interaction. Still, the techniques used are pretty awesome and I loved about client-side security from this post. Great write up!