Closed Bug 1994164 (CVE-2025-13015) Opened 10 months ago Closed 9 months ago

Status panel shows incorrect domain with certain bidi isolation characters

Categories

(Firefox :: General, defect)

Firefox 146
defect

Tracking

()

VERIFIED FIXED
146 Branch
Tracking Status
firefox-esr115 --- verified
firefox-esr140 145+ verified
firefox144 --- wontfix
firefox145 + verified
firefox146 + verified

People

(Reporter: eemeli, Assigned: sthompson)

References

()

Details

(Keywords: csectype-spoof, sec-low, Whiteboard: [adv-main145+][adv-ESR140.5+][adv-ESR115.30+])

Attachments

(5 files, 1 obsolete file)

When a link URL is set to the following:

let shabaka = 'شبكة'
let domain = `${shabaka}.${shabaka}`

link.href = `https://${domain}/\u2066example.com/foo\u2069\u061c`

hovering over the link will show the target as appearing to lead to the example.com domain, but visiting the link will lead instead to the شبكة.شبكة domain.

This is due to us only unescaping directional isolation characters explicitly mentioned in RFC 3987 section 4.1, and not the LRI, PDI, and ALM characters that were added by Unicode after the IRI spec was published.

I intend to file an errata for the RFC separately.

CC Gijs, who appears to have touched this code last.

I don't know to what degree this needs to be sec-sensitive given the public, wontfixed bug 229050. But we should still fix it because this causes us to show the wrong thing for benign / "correct" links (though I suppose that's arguable if these characters appear in it).

Blocks: 299247

Are you happy to keep this in Firefox :: General?

Re: a fix, does a patch need to include all formatting characters in the latest Unicode bidi spec https://www.unicode.org/reports/tr9/#Directional_Formatting_Characters that are not yet being URL-encoded in setOverLink?

  • ALM
  • LRI
  • RLI
  • FSI
  • PDI

Are there good reasons not to handle all of these for setOverLink?

Adding those five characters to the regexp I link above would be the right minimal fix for this. They were added in 2013, and there's no expectation of any more being added.

Alternatively, there's this more elaborate logic that's used for a similar purpose in the location bar; could it be used to also handle URLs in the status panel?

Flags: needinfo?(sthompson)
Blocks: 229050
No longer blocks: 299247

Your POC as a live test, if Bugzilla cooperates:
BMO-linkified plain text: https://شبكة.شبكة/⁦example.com/foo⁩؜
markdown link

Attached file (secure)
Assignee: nobody → sthompson
Status: NEW → ASSIGNED

I posted a patch with a minimal fix.

I wrote a test that I didn't include with the patch. The test case from :eemeli https://شبكة.شبكة/\u2066example.com/foo\u2069\u061c ends up as شبكة.شبكة/%E2%81%A6example.com/foo%E2%81%A9%D8%9C instead of example.com/foo/شبكة.شبكة.

Flags: needinfo?(sthompson)

When Eemeli's test case is shown in the address bar (click on the link in comment 4) there's a / between the Arabic bits and %E2%81%A6. Did you accidentally leave that out of your comment, or is the output actually different from the address bar?

We've had to fix a lot of URL spoofing bugs in the address bar and probably will have more since they keep adding to Unicode. I worry that the "real" underlying bug is that this hover text was formatted by different code than the address bar and that will bite us again and again as we fix bugs in one and forget the other.

(In reply to Daniel Veditz [:dveditz] from comment #4)

Your POC as a live test, if Bugzilla cooperates:
BMO-linkified plain text: https://شبكة.شبكة/⁦example.com/foo⁩؜
markdown link

Should we have a separate Bugzilla-General bug about this? It's clearly doing the same bad thing as Firefox's status panel when linkifying the plain text.

(In reply to Daniel Veditz [:dveditz] from comment #7)

When Eemeli's test case is shown in the address bar (click on the link in comment 4) there's a / between the Arabic bits and %E2%81%A6. Did you accidentally leave that out of your comment, or is the output actually different from the address bar? We've had to fix a lot of URL spoofing bugs in the address bar and probably will have more since they keep adding to Unicode. I worry that the "real" underlying bug is that this hover text was formatted by different code than the address bar and that will bite us again and again as we fix bugs in one and forget the other.

That was my mistake, I did not include the / character between the Arabic script and the \u2066 code point in the test case input. I added that into my test case and the result is the same as what I observe in the Firefox URL bar. I edited my comment 6 to account for that.

I did a quick experiment with using a copy of the code from UrlbarInput https://searchfox.org/firefox-main/rev/644f0db17749554fe23a45b43e77e61f42acdfd9/browser/components/urlbar/UrlbarInput.sys.mjs#5443-5532.

const uri = Services.io.newURI(url, "UTF-8");
url = this.losslessDecodeURI(uri);

produced the same results as

url = Services.textToSubURI.unEscapeURIForUI(url);
url = url.replace(
  /[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,
  encodeURIComponent
);

for the https://شبكة.شبكة/\u2066example.com/foo\u2069\u061c test case, but I don't have a good grasp on the implications for using either approach.

(In reply to Eemeli Aro [:eemeli] from comment #8)

(In reply to Daniel Veditz [:dveditz] from comment #4)

Your POC as a live test, if Bugzilla cooperates:
BMO-linkified plain text: https://شبكة.شبكة/⁦example.com/foo⁩؜
markdown link

Should we have a separate Bugzilla-General bug about this? It's clearly doing the same bad thing as Firefox's status panel when linkifying the plain text.

Please file a product=bugzilla.mozilla.org bug, yes.

Flags: needinfo?(earo)
Flags: needinfo?(earo)

(from comment 9)

but I don't have a good grasp on the implications for using either approach.

I'd certainly be happier for it to use shared code, but in the bigger context of other clean-ups done in both places I think we need to ask Gijs about other implications.

Flags: needinfo?(gijskruitbosch+bugs)
Keywords: sec-moderatesec-low

(In reply to Daniel Veditz [:dveditz] from comment #11)

(from comment 9)

but I don't have a good grasp on the implications for using either approach.

I'd certainly be happier for it to use shared code, but in the bigger context of other clean-ups done in both places I think we need to ask Gijs about other implications.

I passed the review to Marco who I think has the most context here.

Flags: needinfo?(gijskruitbosch+bugs)

This is a multi-product issue that we'd like to start evangelizing so it would be fantastic if we could ship this in 145, and uplift to ESR 140.5. Maybe ESR-115.30 if the patch applies cleanly.

Comment on attachment 9520112 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Easy to moderate level of difficulty
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: beta, release, and ESR are affected. They are tracked
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: Backports will be relatively simple to apply, although I am not familiar with the process
  • How likely is this patch to cause regressions; how much testing does it need?: Low to moderate chance of regressions. I created a single automated test based on the example given in this bug, but I have not checked that test into the tree. I am not familiar with testing across locales nor bidirectional text, so it would be helpful to have QA support.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: No [edited from "I am not sure" due to comment 15]
Attachment #9520112 - Flags: sec-approval?

(In reply to Stephen Thompson [:sthompson] from comment #14)

  • Is Android affected?: I am not sure

Android is not affected; the dialog that comes up when you long-tap on a link already percent-escapes all the directional control characters.

@eemeli would you like me to get you in touch with the authors of the RFC, to check whether this potential errata is already on their radar? (I know Martin Dürst.)

(In reply to Lars Eggert [:lars] from comment #16)

@eemeli would you like me to get you in touch with the authors of the RFC, to check whether this potential errata is already on their radar? (I know Martin Dürst.)

--> ni for Eemeli.

(In reply to Stephen Thompson [:sthompson] from comment #14)

Comment on attachment 9520112 [details]
(secure)

Security Approval Request

This is sec-low, so I will go ahead and queue this for landing. Assuming no issues we should be able to get this into beta without issue.

Flags: needinfo?(earo)

(In reply to Lars Eggert [:lars] from comment #16)

@eemeli would you like me to get you in touch with the authors of the RFC, to check whether this potential errata is already on their radar? (I know Martin Dürst.)

Thanks; as discussed in the interim, I already have a contact/intro for Martin Dürst.

Separately, I've now set up a minimal website to work as a PoC for the exploit:

https://مخادع.شبكة/⁦www.google.com/search?q=⁩؜

The Arabic domain translates to English roughly as scammer.network, and is currently hosted on GitHub Pages.

Flags: needinfo?(earo)
Group: firefox-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 9 months ago
Resolution: --- → FIXED
Target Milestone: --- → 146 Branch

Comment on attachment 9520112 [details]
(secure)

I appreciate the caution when you're not sure, but sec-approval is not needed for an explicit sec-low bug as Gijs noted. Please see the "APPROVAL PROCESS" link in the orange security issue banner for when we insist on it and when we can get out of your way.

Attachment #9520112 - Flags: sec-approval? → sec-approval+
Attachment #9521544 - Flags: approval-mozilla-beta?

Running Nightly with the patch applied, the proof of concept on comment 4 results in شبكة.شبكة/%E2%81%A6example.com/foo%E2%81%A9%D8%9C when hovered and https://شبكة.شبكة/%E2%81%A6example.com/foo%E2%81%A9%D8%9C when visited, which is what we expected.

firefox-beta Uplift Approval Request

  • User impact if declined: Low. Potential for user confusion or user exploitation. Without this patch, some URLs may be displayed in the link preview (when hovering the mouse over a link) differently than the way the URL will actually be loaded due to how the link preview handles bidirectional control characters.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: There is a proof of concept on comment 4 of the bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1994164#c4

When hovering over those links, the link preview in the lower-left of the browser window should NOT look like https://شبكة.شبكة/⁦example.com/foo and instead should include escaped control characters in the URL.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The biggest risk is that this change hasn't been widely tested against example bidirectional URLs, only against the proof of concept in the reported bug. However, this patch applies bidirectional control character escaping logic that is used elsewhere in the codebase, so the approach to the fix is well understood.
  • String changes made/needed: No
  • Is Android affected?: no
Attached file (secure) (obsolete) —
Attachment #9521547 - Flags: approval-mozilla-release?

firefox-release Uplift Approval Request

  • User impact if declined: Low. Potential for user confusion or user exploitation. Without this patch, some URLs may be displayed in the link preview (when hovering the mouse over a link) differently than the way the URL will actually be loaded due to how the link preview handles bidirectional control characters.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: There is a proof of concept on comment 4 of the bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1994164#c4

When hovering over those links, the link preview in the lower-left of the browser window should NOT look like https://شبكة.شبكة/⁦example.com/foo and instead should include escaped control characters in the URL.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The biggest risk is that this change hasn't been widely tested against example bidirectional URLs, only against the proof of concept in the reported bug. However, this patch applies bidirectional control character escaping logic that is used elsewhere in the codebase, so the approach to the fix is well understood.
  • String changes made/needed: No
  • Is Android affected?: no
Attachment #9521548 - Flags: approval-mozilla-esr140?

firefox-esr140 Uplift Approval Request

  • User impact if declined: Low. Potential for user confusion or user exploitation. Without this patch, some URLs may be displayed in the link preview (when hovering the mouse over a link) differently than the way the URL will actually be loaded due to how the link preview handles bidirectional control characters.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: There is a proof of concept on comment 4 of the bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1994164#c4

When hovering over those links, the link preview in the lower-left of the browser window should NOT look like https://شبكة.شبكة/⁦example.com/foo and instead should include escaped control characters in the URL.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The biggest risk is that this change hasn't been widely tested against example bidirectional URLs, only against the proof of concept in the reported bug. However, this patch applies bidirectional control character escaping logic that is used elsewhere in the codebase, so the approach to the fix is well understood.
  • String changes made/needed: No
  • Is Android affected?: no

firefox-esr115 Uplift Approval Request

  • User impact if declined: Low. Potential for user confusion or user exploitation. Without this patch, some URLs may be displayed in the link preview (when hovering the mouse over a link) differently than the way the URL will actually be loaded due to how the link preview handles bidirectional control characters.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: There is a proof of concept on comment 4 of the bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1994164#c4

When hovering over those links, the link preview in the lower-left of the browser window should NOT look like https://شبكة.شبكة/⁦example.com/foo and instead should include escaped control characters in the URL.

  • Risk associated with taking this patch: low
  • Explanation of risk level: The biggest risk is that this change hasn't been widely tested against example bidirectional URLs, only against the proof of concept in the reported bug. However, this patch applies bidirectional control character escaping logic that is used elsewhere in the codebase, so the approach to the fix is well understood.
  • String changes made/needed: No
  • Is Android affected?: no
Attachment #9521549 - Flags: approval-mozilla-esr115?
URL: https://مخادع.شبكة/⁦www.google.com/se...
Attachment #9521544 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9521548 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
Attachment #9521547 - Attachment is obsolete: true
Attachment #9521547 - Flags: approval-mozilla-release?

Quick update

QA Whiteboard: [sec] [uplift] [qa-ver-needed-c146/b145]
Flags: qe-verify+

Reproduced the issue on Firefox 146.0a1 (2025-10-14) on macOS 26.0.1 by using the links provided in Comment 4.

The issue is fixed on Firefox ESR140.5.0 (treeherder), Firefox 145.0b5 and Firefox 146.0a1 (2025-10-22). Tests were performed on macOS 26.0.1, Windows 11 and Ubuntu 24.04.

Attachment #9521549 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+

Stephen, the ESR115 patch does not apply cleanly to the branch, could you update your patch before our last beta end of week please? Thanks

This was downgraded to sec-low, our commitment for the ESR115 branch extension is to backport critical security issues, we could just wontfix it for esr115 if backporting the patch is problematic I guess.

Verified that the issue is fixed on Firefox ESR 115.30.0 (treeheder build). Tests were performed on macOS 26.0.1, Windows 11 and Ubuntu 24.04.

Status: RESOLVED → VERIFIED
QA Whiteboard: [sec] [uplift] [qa-ver-needed-c146/b145] → [sec] [uplift] [qa-ver-done-c146/b145]
Flags: qe-verify+
Whiteboard: [adv-main145+][adv-ESR140.5+][adv-ESR115.30+]
Alias: CVE-2025-13015

Adding jtracey who is working from Thunderbird's side on a related issue (bug 1995509) that might need a related fix to m-c.

See Also: → 2020699
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: