This is apple.com. Rather, at first glance it looks like apple.com, but it’s not.
It’s a fake. It’s not owned by the company Apple but rather this individual, who bought the domain
name and hosted their own website as a proof of concept back in 2017. Fortunately for all of us,
instead of using it for malice and scamming everybody, he decided to be a good person and
tell the security community about it to make sure that this wouldn’t be an issue anymore.
In the worst case scenario, what they could have done is make a website that looks like apple.com,
but instead sends all the information to their own server instead of Apple’s.
You know, like passwords and credit card info.
Wait, this seems like it shouldn’t be possible. Because this is a huge problem, right? I mean,
imagine clicking on an email saying in big bold letters that your account is about to
be deleted and to click on this link to keep your account. Now this piece of spam might be a scam,
but if it looks legit and the url bar says apple.com, you might be inclined to believe them.
So, how was this even possible? You can’t have two apple.coms,
that’s not a thing, otherwise the internet would devolve into chaos,
where everyone can easily pretend to be everyone else. The secret? That’s not how you spell apple.
See, when I spell apple as in apple.com, I say a-p-p-l-e. But that, doesn’t say that.
That first letter there? That’s the cyrillic letter a. That first letter
is not the latin letter a. You can see the confusion here, right? They look identical.
At least, in this font it does. And as you can see, this can be problematic.
Now since then, there have been good defenses against this in the modern browser.
This post was made back in chrome 57, and soon after in chrome 58
Google released some changes to mitigate these vulnerabilities.
But let’s dive into this problem because it’s one of those problems that has quite
a few layers and it’s not a trivial problem to solve. First off, let’s start off by saying that
the internet is global. Lots of people use it, and not everyone uses the same character set.
So the trivial solution of banning certain characters might be okay if
your language doesn’t use them, but you don’t want to do that because if let’s
say you’re a user in China and you just ban all Chinese characters from being in a URL,
you’re going to find that your user experience is going to plummet. If you have any special
rules where you’re not getting the full web experience because of the language you use, even
if it’s something small like a warning, it’s still going to be really annoying to use the internet.
Hey! It’s the security vs convenience trade-off again! You could imagine that every single time
you do anything mildly out of the ordinary your browser stops you by pushing you to the spiritual
equivalent of a TSA line, but that of course would be really annoying. If you want to take a second
pause to think about how you would implement a good trade-off solution here, do so now as I talk
about some of our modern web browsers and how they go about doing it. Really think like a security
developer: how much is this stopping attacks and how much is this hurting user experience?
We should also note that we don’t want to block access to the site. We can show a warning of
course, but a less invasive way is if the url is suspicious or seems malicious or deceitful
because of the characters it uses, to display the url of the page into this format called punycode,
which makes it really obvious that this is not really apple.com and is instead this other thing.
Punycode is basically a way for you to convert all International Domain Names into a much smaller
set of characters of mostly symbols and latin characters. There’s a fairly simple algorithm
for this that we won’t get into, but instead of the vast sets of complex and overlapping
characters that exist in unicode, we instead only have a hundred or so that are part of ascii
Anyways, one of the older solutions that existed was to only allow characters used
in languages in the user’s preferred languages list.
So generally speaking if a user says that they use english and spanish, don’t show them the
urls if they contain Korean characters in the url and vice versa. Convert to punycode and move on.
It’s not perfect, like whenever you want to visit a page from another language,
you have to whitelist that language in your settings just to see the url,
and if you don’t want to, now all your totally valid korean pages have really stupid looking
urls. And so there was an effort to move away from these techniques that utilized language settings.
Then perhaps we should only allow urls if all the characters are from the same character set!
So basically no mixing of different scripts in the URL. This would certainly
solve this problem of the fake a in apple.com, which is a good thing.
But languages are complicated. For example with Chinese, Japanese,
and Korean, there are sometimes multiple sets of scripts that could be used for the language,
so you might sometimes expect there to be two or more different scripts in the url. That means we
have to add specific rules for specific languages, but also sometimes you just mix scripts for the
fun of it! Like adding Japanese and Latin characters together doesn’t seem too absurd.
Oh boy. Okay, so we have language specific exceptions to these rules,
to say that certain character sets can’t be used with each other for example Latin, Cyrillic,
and Greek because they might get confusing, but things like Chinese + Latin is totally fine.
Also there’s not just letters but numbers as well, because there’s multiple numbering
systems and we don’t want to confuse something like Bengali Numerals and Arabic Numerals.
But this doesn’t even work for our apple example because in some fonts, every single letter in
“apple” has a look-alike in the cyrillic language. So you can create a fake apple.com without mixing
any character sets. So perhaps we have to look at the top level domain as well, so if it says
.com perhaps it’s not likely to store a cyrillic URL as compared to something like
.ru or .su. So maybe we need to add a check for something like that as well!
And of course we want to pay special attention to top websites, like we especially don’t want
someone getting into your google or facebook account, so we should probably look out for
things that look particularly similar to google and facebook. So let’s add a clause for that.
AND AFTER ALL THAT, after we don’t show the URL for all these websites and instead show
the punycode, perhaps we also show a warning if it looks a little too suspicious, saying,
are you sure you really want to go here?
Point is, it’s complicated. The techniques I described above are a subset of the rules that
web browsers like Google Chrome and Mozilla Firefox use. Such a simple looking issue with
a lot of baggage with it. Perhaps you have some ideas on a few ways this trade-off could work.
Just be glad that there are people who find these vulnerabilities and instead of exploiting them
help document and resolve them, and also that there are engineers who work
to make your web experience a little safer. Nowadays, if you visit the fake apple.com,
first chrome tells you it is highly suspicious, and when you actually get through to the page,
it looks like this with the url looking like punycode and incredibly suspicious.
So at least you have some warning signs there, which is nice. And One Last Thing: Remember, if
someone emails you a suspicious link, be careful, because it can have scams, and also spoilers.