URL bar spoofing with bidirectional Unicode characters (also link hover text)
Categories
(Firefox :: Address Bar, defect, P3)
Tracking
()
People
(Reporter: arminius, Assigned: mseibert)
References
Details
(Keywords: csectype-spoof, reporter-external, sec-moderate, Whiteboard: [reporter-external] [client-bounty-form] [verif?][snt-scrubbed][adv-ESR115.4+])
Attachments
(2 files)
The URL bar content can be spoofed by mixing bidirectional Unicode characters in specific ways, allowing an attacker to forge the displayed protocol and host.
I'm reporting two variants. (1) is Firefox-specific and seems to be facilitated by URL trimming. (2) affects both Firefox and Google Chrome and seems to point to a general issue with how the parts of bidirectional URLs are reordered.
(1)
In a text, the first occurring strong (i.e. directional) character determines the base direction. In the URL bar, this is usually the h
of http
. However, Firefox strips http://
from plain HTTP URLs (if browser.urlbar.trimURLs == true
, as is the default). In that case, the first character of the hostname determines the text direction. So, if a hostname from an RTL script is chosen (which passes the IDN display algorithm without being altered, e.g. an Arabic or Hebrew word), the entire URL string is displayed with RTL as the base direction. This arranges parts of the URL in unexpected ways.
Proof of concept
http://xn--tib.ml/index%F0%90%A9%96https://www.mozilla.org/articles
appears in the URL bar ashttps://www.mozilla.org/articles𐩖ml/index.ٴ
, spoofing both the HTTPS protocol and full host. (I've chosen an Arabic letter as the second-level domain name and an RTL slash-lookalike (U+10A56
) as a convincing path separator, although the latter isn't a requirement for the attack.)- Similarly, a hostname with European numbers (because they aren't strongly directional) and an RTL top-level domain could be used, e.g.:
http://123.456.קום/https://www.mozilla.org/articles
which displays ashttps://www.mozilla.org/articles/קום.123.456
(2)
Both Firefox and Google Chrome seem to implement the same display algorithm for URLs with bidirectional text, which gives unexpected results if both the hostname and path contain RTL sequences. In particular, if the hostname ends with an RTL part, and the path starts with an RTL character, both are interpreted as a continuous RTL context and get visually re-ordered. This way part of the path ends up in the hostname and vice versa. This also means that an attacker can (visually) inject characters into the hostname which are on the IDN blocklist but don't get blocked here because they are actually part of the path segment, not the domain name.
Proof of concept
https://www.mozilla.org.xn--tib.xn--9dbq2a/#%F0%90%A9%96/app/main
displays ashttps://www.mozilla.org.𐩖#...
- Also, an RTL-only hostname can trivially be shadowed by another RTL hostname:
https://ק.קום/م.كوم/foo
requestsק.קום
although visuallyم.كوم
follows after the protocol part. - Since numbers aren't strongly directional, one can also trivially spoof IP hosts. E.g.,
https://127.xn--9dbq2a/0.0.1/
andhttps://127.ק.קום/0.0.1/index.php
both visually start withhttps://127.0.0.1/
but request a different hostname.
All examples were tested on Linux + Nightly with default settings.
Comment 1•4 years ago
•
|
||
:jfkthame, can you help take a look at what's happening here?
Reporter: thanks for the report. I'm assuming you've reported to Chrome as well. Can you link us to your report there so we can avoid zero-daying them if we fix first and/or ensure that fixes are complete etc. ? (Fine if the Chrome report is hidden from the public, we can ask them for CCs if we know which it is.)
Comment 2•4 years ago
|
||
This seems quite related to the issues in bug 1623888, although here the examples aren't relying on overflowing the available space, they're just about reordering the pieces so that it's unclear what the actual domain is. (I believe we correctly show the domain darker than the rest of the URL in each case, but it may be easy to overlook that when what looks like a normal domain name is visually at the beginning.)
Comment 3•4 years ago
•
|
||
Similarly to bug 1623888, we could insert nonbreaking/forcing chars where necessary (for case 1 when we strip http, for case 2 between the host and the path), but again it would add a lot of complication to have a visible value different from the real input value when we calculate selection and highlight. With Bug 1577539 fixed things could maybe be easier, since we'd only format fixed and confirmed URLs, rather than any string.
I must think a bit more about this and experiment a little.
Reporter | ||
Comment 4•4 years ago
|
||
Reporter | ||
Comment 5•4 years ago
|
||
:Gijs Sure, just filed it. Chromium ticket: https://bugs.chromium.org/p/chromium/issues/detail?id=1175415
I believe we correctly show the domain darker than the rest of the URL in each case, but it may be easy to overlook that when what looks like a normal domain name is visually at the beginning.
Yep, the fake hostname will be more grey. That said, in some scenarios (e.g. a rogue WiFi AP), a non-ICANN hostname can be used to make Firefox stop greying out anything - e.g. http://xn--tib.index/test𐩖https://accounts.google.com
shows as https://accounts.google.com/...
in all black. Or, as in my examples, a very short IDN domain name can be used to make the URL appear more consistently grey (I used U+0674 which is barely visible).
:mak Note that the port will have to be separated from the host too, otherwise it's shuffled with the domain parts. E.g.:
https://xn--seb.xn--9dbq2a:8080/%D7%A7%D7%95%D7%9D
https://1234.xn--9dbq2a:5678/some/path
Maybe it could also be an option to fall back to punycode and/or URL-encoding the path for misbehaving URLs. Given the (possibly?) rare number of cases where this issue occurs naturally, the impact on UX may be tolerable.
Also, just adding that the examples of (2) generally apply to link hover texts, too.
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Comment 8•2 years ago
|
||
(In reply to Armin Ebert [:arminius] from comment #5)
Yep, the fake hostname will be more grey. That said, in some scenarios (e.g. a rogue WiFi AP), a non-ICANN hostname can be used to make Firefox stop greying out anything - e.g.
http://xn--tib.index/test𐩖https://accounts.google.com
shows ashttps://accounts.google.com/...
in all black. Or, as in my examples, a very short IDN domain name can be used to make the URL appear more consistently grey (I used U+0674 which is barely visible).
The highlighting has been fixed in bug 1704420.
To further improve the situation we plan to introduce a direction character when we remove the protocol (bug 1833091). There may still need to be further work after that.
Updated•2 years ago
|
Comment 10•2 years ago
•
|
||
(In reply to Mark Banner (:standard8) from comment #8)
There may still need to be further work after that.
There is further work we are doing in bug 1836962, though we may have to change approach because introducing invisible characters is proving to be complicate, we must manipulate the selection and that breaks a ton of tests and may introduce regressions.
It may be possible to "simulate" the same behavior in the input field itself (we briefly discussed this with @jfkthame), but in the meanwhile we could decide to just not trim when directionality changes after trimming.
Just wanted to point out that work is ongoing.
Comment 11•2 years ago
|
||
Comment 12•2 years ago
|
||
To sum up a bit the situation here:
- highlighting was improved, so we don't end up not hilighting anything that may be confusing. Afaict the highlight is correct now.
- we don't trim the protocol anymore if by doing that we end up changing the initial directionality of the URL. This is a temporary solution until we can get support in the input field itself to "force" the first character directionality (I filed bug 1856384 for this).
The remaining things are:
- have a clear indicator of the address bar status, whether it contains the current URI, or an edited string or a persisted search term. This is pretty much covered by Bug 1850690
- Evaluate alternative approaches for the default address bar visualization, that advanced users could disable if they wish to have normal access to full URLs. That's being discussed in bug 1624703.
I think we can consider this resolved, as the workarounds bring this issue on par with previous solutions (formatting and proper bidi). The remaining enhancements remain open for a continuation of the work.
Comment 13•2 years ago
|
||
IIUC, bug 1836962 and bug 1833091 implemented the changes referenced in comment 12? Can we set the dependencies? Also, those landed in 116/117 - do we need to do any follow-up work for ESR115 still?
Comment 14•2 years ago
•
|
||
(In reply to Ryan VanderMeulen [:RyanVM] from comment #13)
IIUC, bug 1836962 and bug 1833091 implemented the changes referenced in comment 12? Can we set the dependencies?
We usually don't link non secure bugs to secure bugs.
Also, those landed in 116/117 - do we need to do any follow-up work for ESR115 still?
bug 1704420 is the right one for highlighting and it's fixed in 115.
bug 1833091 is no longer related to this issue. That was the initial plan but it ended up being really hard, so we ended up with bug 1836962. So it's not necessary to uplift that work.
Bug 1836962 may be interesting to uplift, yes. I'll ping Marc about that.
Comment 15•2 years ago
|
||
(In reply to Marco Bonardo [:mak] from comment #14)
We usually don't link non secure bugs to secure bugs.
That was fixed awhile ago. You can safely do so now - secure bug dependencies aren't shown to users who can't access the bugs in question.
bug 1704420 is the right one for highlighting and it's fixed in 115.
bug 1833091 is no longer related to this issue. That was the initial plan but it ended up being really hard, so we ended up with bug 1836962. So it's not necessary to uplift that work.
Bug 1836962 may be interesting to uplift, yes. I'll ping Marc about that.
Thanks
Updated•2 years ago
|
Comment 16•2 years ago
|
||
Bug 1836962 was uplifted to ESR115
Updated•2 years ago
|
Comment 17•2 years ago
|
||
Updated•2 years ago
|
Updated•1 years ago
|
Updated•1 year ago
|
Description
•