Closed Bug 1690979 (CVE-2023-5732) Opened 4 years ago Closed 2 years ago

URL bar spoofing with bidirectional Unicode characters (also link hover text)

Categories

(Firefox :: Address Bar, defect, P3)

defect

Tracking

()

RESOLVED FIXED
117 Branch
Tracking Status
firefox-esr115 119+ fixed
firefox117 --- fixed

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 as https://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 as https://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

All examples were tested on Linux + Nightly with default settings.

Flags: sec-bounty?

: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.)

Type: task → defect
Component: Security → Address Bar
Flags: needinfo?(jfkthame)

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

Flags: needinfo?(jfkthame) → needinfo?(mak)

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.

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

Summary: URL bar spoofing with bidirectional Unicode characters → URL bar spoofing with bidirectional Unicode characters (also link hover text)
Severity: -- → S3
Priority: -- → P3
See Also: → CVE-2021-4221
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(mak)
Flags: sec-bounty? → sec-bounty+
Duplicate of this bug: 1832243

(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 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).

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.

Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?][snt-scrubbed]
See Also: → 1844915
Duplicate of this bug: 1844915

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

To sum up a bit the situation here:

  1. highlighting was improved, so we don't end up not hilighting anything that may be confusing. Afaict the highlight is correct now.
  2. 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:

  1. 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
  2. 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.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED

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?

Group: firefox-core-security → core-security-release
Flags: needinfo?(mak)

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

Flags: needinfo?(mak)

(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

Assignee: nobody → mseibert
No longer blocks: CVE-2023-37205
Depends on: CVE-2023-37205, 1836962
Target Milestone: --- → 117 Branch
Whiteboard: [reporter-external] [client-bounty-form] [verif?][snt-scrubbed] → [reporter-external] [client-bounty-form] [verif?][snt-scrubbed][adv-ESR115.4+]
Alias: CVE-2023-5732
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: