This flaw was reported to both Google and Opera on 23rd October 2014.
International Domain Names are great! They open the web up to the whole world and allow me to own a domain like 莎士比亚.org.
But they are a constant battleground in the fight for security.
Homograph attacks are when someone uses two letters or symbols which look the same, to fool a user into visiting the wrong web address. For example TW1TTER.com has the number 1 rather than the letter i. Most fonts are reasonably good at helping users disambiguate between similar characters – but it’s not always possible.
The Homograph Strikes Back
Unicode allows for “Combining Characters”. This allows us to easily add an accent to an existing character. The two characters should display as one. Well, that’s the theory.
If we combine the letter “g” with ̶ (Combining long stroke overlay) we get “g̶” (it should display as “
g” on your screen).
On certain Android phones, and on the Opera browser for Android, it does not. It just shows up as “g”.
Here’s an example of the attack.
- A malicious user registers the domain name “g̶o̶o̶g̶l̶e̶.com” (In Punycode it looks like xn--google-37dbbbbb.com)
- They send a plain text email / Tweet / or some other communication telling people to visit g̶o̶o̶g̶l̶e̶.com
- The Android phone displays the link as “google.com”
- The user clicks – and is taken to a page which illegitimately asks for her Google credentials.
This appears to be a problem with the Android Operating System. Although Google’s Chrome isn’t affected, other system apps like Gmail are – as are any 3rd party apps which rely on Android’s text rendering. This appears to be why Opera is vulnerable but Firefox is not.
I’ve tested this on Android 4.4.4 – the latest public release of Android. I assume older versions are vulnerable as well.
Here’s Google’s latest “Gmail” app being sent the plain text “Testing http://g̶o̶o̶g̶l̶e̶.com”.
Long pressing on the link displays correctly.
As you can see above – the user sees a link that appears to go to “google.com” even though it goes to an alternate address.
The same issue also affects the new “Inbox” app, as well as default Android apps like Calendar, Messaging, Hangouts, etc. It also affects most of the apps which attempt to render plain text using Android’s default libraries.
I wondered what was causing this issue. I believe it is a problem with the default “Roboto” font used by Google. If I switch the system to use an alternative font, the system renders the text very differently.
In this case, using Source Sans Pro, the strike-through is rendered as an unknown character rather than silently failing.
We can prove this by looking at the Roboto font from Android 4.4 via FontForge – the Strike Through Character is missing.
When we take a look at the Roboto font from the Android 5.0 release – we can see that the problem has been fixed.
This means that the GMail app and all other system apps correctly render the text. Here is the same email on Android Lollipop.
I disclosed this to Google on 23rd October. Their (very prompt) reply was:
unfortunately Android apps do not fall in scope for the vulnerability reward program (apart from Google Wallet, see http://www.google.com/about/appsecurity/reward-program/index.html), but I will pass this information along internally. Thanks!
Personally, I consider this to be a deficiency with the underlying Android OS. The default font which is bundled with modern Android phones is defective. This couldn’t be described as a fundamental flaw, but it does highlight the problem of relying on accurate text rendering.
I mentioned the source of the issue to Google. To their credit, they quickly replied with:
… it seems like there was an issue in the Android KitKat (and earlier) releases that can cause some text to be rendered without the strikethrough, but it’s been fixed in Lollipop.
…Because it appears that this issue is already fixed in the upcoming release and it’s not high severity enough to backport to earlier releases, we’re going to close this ticket out. If you think we missed something, please let us know.
Nice work isolating the issue to the Roboto font. I have no problem with you writing a blog post about this issue.
Initially, I believed this to be a bug solely in the Opera browser and so I reported this to them. I noticed that when viewing a link on Twitter, it displayed as “hunger.com” rather than “h̶u̶n̶g̶e̶r̶.com”.
Their (fairly sensible) reply was – “not a security bug”
We have looked further into the issue, and have determined that it is not an exploitable security issue.
Basically, Opera on Android will not render it correctly in a web page. That is a bug, but web pages can already display whatever confusing content they want anyway – they could just as easily use this:<a href="http://evil.com/">http://good.com/</a>
This is not something a browser can prevent – a page could just as easily use an image of text instead. This has always been required by the relevant HTML/CSS specifications.
So, we will look into fixing the display of strikethroughs within a web page, but that will be fixed as a regular bug, not an exploitable security issue.
It’s hard to call this a true exploit – it would require the user to ignore the URL bar in their browser – although if a malicious web page were to force itself into full screen mode, the user wouldn’t stand a chance.
Given that Punycode has been around for over a decade, and that the ̶ character has been in Unicode since 1993, it is more than a little disappointing that Google took so long to include it in their text rendering engine.
In the seminal paper “The Homograph Attack” by Evgeniy Gabrilovich and Alex Gontmakher – the authors concentrated on how browsers should work to fight against these attacks:
More practically, the browser can highlight international letters present in domain names with a distinct color, although many users may find this technique overly intrusive. A more user-friendly browser may only highlight truly suspicious names, such as ones that mix letters within a single word.
For additional security, the browser can use a map of identical letters to search for collisions between the requested domain and similarly written registered ones
In today’s interconnected app-driven world, every single program which can display a URL must ensure that the user is not misled into clicking on a fraudulent link.