Update. Apple iOS 12 and Safari 12 for macOS, released on 2018-09-17, fixed this flaw.
We’ve seen quite a few articles out there telling you to Beware! if you use the Safari browser, because Attackers Can Spoof URLs!
This sounds like a serious issue, worthy of the boldfaced exclamation points we’ve used above, and here’s why.
A spoofed URL is where the address bar at the top of your browser shows a website name that is deliberately and misleadingly different from the web page displayed in the browser itself.
That’s not supposed to happen.
The content served up by a website can display pretty much anything it wants in the main browser window, including fraudulent text and other people’s logos, but the address bar itself is supposed to be sacrosanct.
By carefully keeping the address bar under its own control, your browser aims to help you spot bogus content.
Crooks can present you with a fake bank login page, for example, but they can’t rewrite the address bar to claim that the site really is your bank’s – at least, they’re not supposed to be able to.
In fact, if you take a careful look at the address bar before you enter personal data, you’ll be able to detect and avoid the vast majority of phishing attacks, because the address bar is the one part of your browsing experience that the crooks can’t easily manipulate.
Because of this, these widespread warnings about an unpatched URL spoofing hole in Safari piqued our interest, and we decided to dig into the story a bit.
Safari may be a minority desktop browser these days – it’s only available on the Mac, where it faces stiff competition from Google Chrome and Mozilla Firefox – but it’s widely used on the iPhone and iPad, where it’s the default, pre-installed system browser.
The bug turns out to be a really simple one, and here’s how it works.
Imagine you have a simple web page like this, hosted at the site
A visitor will see something like this, with the website name clearly denoted in the address bar:
Here, we’re redirecting to the web page
other.test immediately after displaying the “here is some content” text:
As you can see, when the
location.assign happens, the browser correctly updates the address bar with the name of the new location,
But if we tweak the URL to which we’re redirecting so that it specifies a bogus network port (HTTP servers use port 80 by default; HTTPS uses port 443), the browser will try to connect to a port that isn’t listening, and after a fairly lengthy timeout period, will report an error.
In Firefox, for instance, you won’t see anything misleading while the browser is waiting for the
location.assign, but after it’s tried and failed you’ll see the new location in the address bar plus an error message in the main window:
So far, so good.
But Safari’s bug is that it updates the address bar as soon as the redirect attempt starts, showing the name of the new website, but leaving the old content visible in the main window until the redirect fails.
For a minute or more, therefore, you’ll see content from
ns.example but an address bar identifier saying that the site’s name is
It turns out that Safari won’t let you type anything into the web form shown above while the
location.assign() function is trying to do the redirect, so even though you can click the [Submit] button, you can’t directly leak any data thinking you’re on a different website.
ns.example) rather than to the site declared in the address bar (
There you have it: URL spoofing.
On an iPhone, the bug is a bit more troublesome – to save space on the screen, mobile Safari shows only the website name, without the telltale text
:8000 (or whatever the port number is) at the end:
Sure, you might not pay attention to the bogus port number even if it were displayed, but it is a handy giveaway in the desktop version of Safari.
What to do?
According to the researcher who reported this flaw, both Edge and Safari used to have this “display new URL’s name before the content is ready” bug, but Microsoft patched Edge back in August.
Edge now behaves like Firefox: while the
ns.example content is on the screen, the address bar shows
ns.example; only after the browser has tried and failed will the new URL be shown, at the same time that the error message pops up.
Apple, however, hasn’t yet changed the behaviour of Safari. (We’re wondering if the soon-to-be-released iOS 12 will quietly include a fix for this. [It did – see note at top of article.])
You can spot this spoofing trick, however, even on the mobile version of Safari where the giveaway port number is suppressed:
- The thin blue progress line under the address bar stops moving half-way. This shows that the page named in the address bar hasn’t actually loaded yet, so it’s a useful indicator that the address bar denotes what’s still to come, not what is currently on the screen.
- There’s no padlock in the address bar. The redirect isn’t going to succeed because the URL is dud, so Safari can’t display an HTTPS certificate because there isn’t one, and never will be.
You really ought to be looking out for the HTTPS padlock these days, even for sites where you don’t intend to login or fill in any forms.
A plain old HTTP site is just too easy for crooks to impersonate, so our recommendation is to stay away from non-HTTPS content entirely – a precaution that will handily protect you in this case, too.