Comments (13)
UPDATE: never mind, this seems to still work...
Say @masatokinugawa , any chance Safari dropped support for SVG font-face?
- According to MDN, font-face support via SVG dropped at Safari version 16.4
- According to Wikipedia, Safari 16+ was introduced in 2022
- Your research is from 2021, so before this was dropped
Am I missing something?
Because if they did, this will save me a lot of trouble
from lavadome.
In my blog article, I assume that an attacker can only inject CSS and can't execute JS. That is the reason why I used image requests for the leak.
In situations where an attacker can execute JS, they don't need to use images, just look at the scrollWidth
property as I did in the PoC above. Therefore, even if strict CSP is used, the leakage is still possible.
Although I haven't been able to create a working SVG font PoC for LavaDome yet because Safari does not apply the ::first-line
properly, at least I confirmed that the ligature is actually created and the scrollWidth
is changed, so all we need to do should be adjust the PoC for Safari.
from lavadome.
I'm closing this for now, not because this vector is impossible, but because I prefer to only leave issues open when they indicate a practical way to perform a bypass, as opposed to theoretical only.
from lavadome.
First of all, truly amazing (hats off @securityMB).
Can you help me understand something - is the fetching of a font required to be external AFAYU?
Or would this work similarly by forming the font on the client side without having to reach out to external servers?
Understanding this will help me determine the criticality level of this attack and what requirements must be met for attackers to succeed (a need to communicate with a server and load fonts is more likely to meet limitations such as network-CSP than a local-only attack)
Thanks again for toying around with LavaDome @masatokinugawa!
from lavadome.
Drive-by comment: I think it theoretically should be possible to create the font client-side.
Masato used https://www.npmjs.com/package/svg2ttf in the proof-of-concept and if this library can also work in the client-side JS, then this attack should work without having to contact any server.
That said, I think you can still contain the attack with CSP since with local attacks you would probably still need either data:
or blob:
URLs to be able to load the font.
from lavadome.
Exactly what I was thinking, just wanted to make sure my intuition was correct. Thank you.
So with proper font-src CSP configuration it should be very straight forward to mitigate this vector - would you agree?
from lavadome.
Because honestly, I think setting up a well-thought font-src
directive is a very fair requirement from products that are willing to adopt LavaDome into their apps. If adding this requirement into the README under usage
will be the mitigating force of LavaDome, this might be the course of action we will chose to take.
from lavadome.
Unlike other modern browsers, Safari supports SVG fonts. This allows using Michał's trick with SVG only, without converting fonts to TTF, WOFF, etc.: https://mksben.l0.cm/2021/11/css-exfiltration-svg-font.html
Or would this work similarly by forming the font on the client side without having to reach out to external servers?
In the case of SVG fonts, all font components can be defined by putting them to HTML directly, so there is no need to fetch external URLs. Therefore, using Safari + SVG fonts, it still should work even if the strict CSP font-src
is configured.
from lavadome.
One more question, if I may @masatokinugawa,
Trying to study your research - is it true to assume, that while forming fonts in Safari does not require external connection (thanks to SVG), this isn't the case for the part where the secret is being leaked, in which external communication is necessary - right?
In other words - using this SVG technique in Safari will only work by leaking each char to a remote server, and there's no way to access this leakage in the client without needing a remote server, if I understand correctly.
And if so, if I manage to implement strict network CSP to my app which successfully enforces a whitelist of domains it can communicate with, this should mitigate your SVG attack - is this right in your opinion?
I'm saying this because it seems from your research that the leakage of the secret happens using background: url
, correct?
So for example, would you agree that Content-Security-Policy: default-src: "self"
is enough to block this attack?
from lavadome.
I think I understand your PoC and general approach better now @masatokinugawa.
I think I made some progress on your idea with SVG instead of font against Safari, where I manage to successfully capture only a single char but not the rest.
I can see why first-line
would've completed the bypass for you, but I too can't seem to make it work in Safari.
Any ideas on how to continue this? Couldn't find any other pseudo elements/classes to use here instead.
setTimeout(() => {
const container = document.body.appendChild(document.createElement('div'));
const defaultWidth = document.body.scrollWidth;
const secretChars = "0123456789abcdef";
let index = 0;
let foundChars = "";
const style = document.createElement('style');
document.body.appendChild(style);
style.innerHTML = `#PRIVATE {
font-size:0;
width:0;
word-wrap: break-word
}
#PRIVATE:is(*) {
font-family:hack;
font-size:100px
}`;
const xxx = () => {
if (defaultWidth < document.body.scrollWidth) {
foundChars += secretChars[index];
console.log(`Found: ${foundChars}`);
index = 0;
} else {
index++;
}
if (foundChars.length === 32) {
alert(foundChars);
} else {
loadFont(`${foundChars}${secretChars[index]}`);
}
};
const loadFont = target => {
setTimeout(xxx, 1000);
console.log('load font:', target);
container.innerHTML = `
<svg>
<defs>
<font horiz-adv-x="0">
<font-face font-family="hack" units-per-em="1000" />
<glyph unicode="${escape(target)}" horiz-adv-x="99999" d="M1 0z"/>;
</font>
</defs>
</svg>`;
};
loadFont(secretChars[index]);
}, 3000);
from lavadome.
Since #47 is merged, the responsibility to mitigate this attack surface officially shifts to the developer since it requires CSP.
That leaves us with Safari only, where CSP can be bypassed using SVG fonts instead (theoretically).
(Removing chrome
& firefox
labels)
from lavadome.
The reason why the SVG font leak doesn't work well seems to be because Safari doesn't create ligatures when elements are separated. e.g.:
<!-- Safari can create "AB" ligature -->
<span>AB</span>
<!-- In this case, can't -->
<span>A</span><span>B</span>
I haven't found a way to leak all characters well yet. The browser's behavior with regards to ligatures seems quite inconsistent :(
from lavadome.
I salute your effort and willingness to help either way @masatokinugawa, thanks for your research, you helped significantly making LavaDome safer 🫡
from lavadome.
Related Issues (18)
- Support React framework HOT 1
- LavaDome is vulnerable to selection API HOT 2
- LavaDome is vulnerable to font-face based leak attack HOT 1
- Audit defensive coding HOT 2
- Make demo great HOT 1
- LavaDome bypass via text fragments HOT 11
- LavaDome bypass via Screen Capture API HOT 1
- LavaDome is vulnerable to onmouseover HOT 1
- LavaDome bypass via overridden built-in methods HOT 2
- Add tests
- Defend from extension content scripts HOT 5
- Refuse to load LavaDome within non-top documents HOT 1
- Support copy to clipboard
- LavaDome bypass by detecting character height HOT 5
- AI generated logo wanted
- Add release-and-publish GHA CI workflows
- Safari support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lavadome.