Closed Bug 1952213 (CVE-2025-3029) Opened 7 months ago Closed 7 months ago

Firefox Desktop Address Bar Spoofing Using RTL Character and \u{E012A}

Categories

(Firefox :: Address Bar, defect, P1)

defect

Tracking

()

VERIFIED FIXED
138 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr128 137+ verified
firefox136 --- wontfix
firefox137 + verified
firefox138 + verified

People

(Reporter: renwax23, Assigned: mak)

References

(Regression)

Details

(4 keywords, Whiteboard: [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+][adv-esr128.9+] )

Attachments

(8 files)

This is similar to previous issue which the fix was incomplete, when visiting a domain or a subdomain which has an RTL character inside with a long URL we can hide the origin and only show the end of the URL, path or other queries.
Firefox allows one whitespace but by using \u{E012A} with a whitespace we can have unlimited whitespaces inside the address bar, the attack is now like this:

  • RTL character inside the domain with a long query parameter
  • Firefox hides the origin only shows the query parameter value
  • Using \u{E012A}+%20 we clear out the address bar
  • Insert accounts.google.com in beginning of the query parameter

POC: https://%DA%A9%D9%88%D8%B1%D8%AF.pwr.wtf/poc.html (It might not work perfect for you because it's adjusted for my window width size, change your window bigger or smaller to see how it looks)

POC Video/Photo attached too

Code Used:

location='https://xn--ugbd2e0t.pwr.wtf/poc.html?\u{20}\u{E012A}\u{20}accounts.google.com'+'\u{E012A}\u{20}'.repeat(167)+'.' 

Thanks
Renwa

Flags: sec-bounty?

(In reply to Renwa from comment #0)

Created attachment 9470247 [details]
Screen Recording 2025-03-06 at 3.55.03 PM.mov

This is similar to previous issue which the fix was incomplete

Please please please always link issues. Which previous issue? Do you mean bug 1925496? Right now it's unclear.

Component: Security → Address Bar
Flags: needinfo?(renwax23)

Yeah I mean bug 1925496 sorry about that.

Flags: needinfo?(renwax23)

Sometimes the scheme doesn't show up so we can insert the https:// by ourselves which it would look like the attachment.

This is part of Variation Selectors Supplement, we're already handling U+180B … U+180D and U+FE00 … U+FE0F, though we're not handling U+E0100 … U+E01EF. I don't think there's a regex group for these.
Around here: https://searchfox.org/mozilla-central/rev/d5baa11e35e0186c3c867f4948010f0742198467/browser/components/urlbar/UrlbarInput.sys.mjs#5091-5092,5107

The difference related to the the protocol being shown or not sometimes is likely related to the Scotch Bonnet rollout, a partial redesign of the urlbar that also strips https (we're now showing a "not secure" label for http). If the feature is enabled we don't separate anymore the protocol. Anyway I think it's not important for this bug, what matters is the set of invisible characters.

Ah, maybe \p{Variation_Selector} could be used, checking, but it seems to be working in the Console.

It's unclear whether these should be encoded only when they are adjacent to a space, or always, though I'd propend for the latter.
According to https://en.wikipedia.org/wiki/Variation_Selectors_Supplement these can potentially be used to digitalize cultural heritage, thus I suspect they are unlikely to be useful for modern URLs.
Opinions?

Assignee: nobody → mak
Severity: -- → S2
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Flags: needinfo?(jfkthame)
Priority: -- → P1
Whiteboard: [client-bounty-form] → [client-bounty-form][sng]

U+E012A is VARIATION SELECTOR-59, and in UTF-16 would be encoded as 0xDB40 0xDD2A. In that form, it looks to me like the regex mentioned in comment 6 ought to be detecting it; specifically, the alternative [\udb40-\udb43][\udc00-\udfff] should match. Is it failing to do so?

Yeah, a quick test in the console shows this not matching:

>> "A\u{e0100}Z".replace(/[\udb40-\udb43][\udc00-\udfff]/gv, "x").split("")
<< Array(4) [ "A", "\udb40", "\udd00", "Z" ]

Checking documentation..... this would be because with the /v flag on the regex, we're dealing with Unicode code points and not with UTF-16 code units. (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode)

To replace the supplementary-plane variation selectors, then, we need to express them as code points, not as surrogate pairs:

>> "A\u{e0100}Z".replace(/[\u{e0100}-\u{e01ef}]/gv, "x").split("")
<< Array(3) [ "A", "x", "Z" ]

So I think the issue here is actually that all the non-BMP elements of that regex are broken. They need to be written in terms of Unicode code points, not as pairs of high- and low-surrogate code units.

Looks like we introduced this issue in bug 1925496 when the /v flag was added to the regex (to allow use of Unicode property-based character classes); at that time, the parts of the regex that used to match individual surrogate code units (in a non-Unicode-aware regex) should have been updated to use Unicode code points.

Flags: needinfo?(jfkthame)
Keywords: regression
Regressed by: CVE-2024-11695

Set release status flags based on info from the regressing bug 1925496

setting test landing date based on Firefox 137 release date, assuming we'll uplift to it.

Whiteboard: [client-bounty-form][sng] → [client-bounty-form][sng][reminder-land-tests 2025-04-29]
Group: firefox-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 138 Branch

Can we get an uplift request for 137? Thanks

Flags: needinfo?(mak)
Attachment #9473580 - Flags: approval-mozilla-beta?

beta Uplift Approval Request

  • User impact if declined: Some characters are shown as invisible in the address bar, while they should be encoded, this may cause confusable addresses
  • Code covered by automated testing: no
  • Fix verified in Nightly: no
  • Needs manual QE test: yes
  • Steps to reproduce for manual QE testing: see comment 0
  • Risk associated with taking this patch: low
  • Explanation of risk level: the patch fixes a Regex that was not matching unicode surrogates correctly
  • String changes made/needed: none
  • Is Android affected?: no
Flags: qe-verify+
Attachment #9473584 - Flags: approval-mozilla-esr128?

esr128 Uplift Approval Request

  • User impact if declined: Some characters are shown as invisible in the address bar, while they should be encoded, this may cause confusable addresses
  • Code covered by automated testing: no
  • Fix verified in Nightly: no
  • Needs manual QE test: yes
  • Steps to reproduce for manual QE testing: See comment 0
  • Risk associated with taking this patch: low
  • Explanation of risk level: the patch fixes a Regex that was not matching unicode surrogates correctly
  • String changes made/needed: none
  • Is Android affected?: no
Flags: needinfo?(mak)
Attachment #9473580 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9473584 - Flags: approval-mozilla-esr128? → approval-mozilla-esr128+
QA Whiteboard: [qa-triaged]

I've reproduced this issue using an affected Nightly build (2025-03-06) on Win 11, with STR from comment 0.

The issue is verified as fixed on the latest builds, Nightly 138.0a1, Beta 137.0b10 and Esr 128.9.0 (treeherder builds). Tested with macOS 14, Ubuntu 24.04 and Win 11.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
Attached file advisory.txt
Whiteboard: [client-bounty-form][sng][reminder-land-tests 2025-04-29] → [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+]
Whiteboard: [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+] → [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+][adv-ESR128.9+]
Flags: sec-bounty? → sec-bounty+
Comment 11 is private: false
Whiteboard: [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+][adv-ESR128.9+] → [client-bounty-form][sng][reminder-land-tests 2025-04-29][adv-main137+][adv-esr128.9+]
Alias: CVE-2025-3029
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: