Closed Bug 1940339 Opened 1 month ago Closed 27 days ago

declarativeNetRequest has broken history handling

Categories

(WebExtensions :: Untriaged, defect)

Firefox 136
defect

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 1826867

People

(Reporter: Moritz.Hedtke, Unassigned)

Details

(Keywords: reporter-external)

Attachments

(1 file, 1 obsolete file)

Attached file firefox-extension-bug.zip (obsolete) —

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0

Steps to reproduce:

Note: I'm relatively sure this is not a security issue but still marked it as one just to be safe. Maybe this is somehow exploitable for spoofing the URL or so.

It seems that declarativeNetRequest with redirect to an extension page breaks the history navigation in different ways.

  1. Install the attached extension (e.g. using Debug Add-ons)
  2. Go to https://example.org/
  3. You will get redirected to the extension page
  4. Click the pushState button

Actual results:

  1. Then navigating back shows a file:/// url to the extension's file in the URL bar
  2. Reloading the page now also breaks in different ways (sometimes
    "Access to the file was denied", sometimes blank page)

Expected results:

The history navigation should behave normal with correct URLs and no access errors

Product: Firefox → WebExtensions
Flags: needinfo?(dveditz)

I can't reproduce this by manually loading an extension page and then using pushState in this way. Once I navigate away from the extension page (loading a new domain or going back) the extension page no longer shows up in the session history list (right-click on the back arrow). Other "substituting schemes" like resource:///chrome.manifest, about:preferences, or chrome://branding/content/about.png DO stick in the session history. That seems a little odd to me. Is there a UX or philosophical reason to treat moz-extension: URLs differently from chrome: urls in session history? Or was it simply that it raised a lot of broken edge cases that weren't worth the time to fix? If it was the latter maybe this technique is exposing some of those broken edge cases.

(one future potential problem would be if we randomize the GUIDs every startup like Safari, instead of our current practice of assigning them at initial install. Maybe mostly fine since a new startup should be a new session, but we'd have to do something about Session Restore)

Is the redirect getting saved in the HTTP cache, but in the raw "after substitution" jar:file:/// form pointing at the extension?

Flags: needinfo?(dveditz) → needinfo?(lgreco)

I agree with Moritz that this doesn't seem like a security bug. Broken, but in raw file:/// form the extension pages will not have any of the powers of a web extension. On the other hand it might then get access to load file:/// urls without having to get permission for it

I couldn't test the extension because I got a "does not contain a valid manifest" error (using Nightly). I'll leave it to the web extension team from here.

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

I couldn't test the extension because I got a "does not contain a valid manifest" error (using Nightly). I'll leave it to the web extension team from here.

Although the "Load Temporary Add-on..." popup claims that you can directly load .zip files it seems like this does not work. You need to unpack the zip first and select the manifest.json file.

(In reply to Moritz Hedtke from comment #3)

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

I couldn't test the extension because I got a "does not contain a valid manifest" error (using Nightly). I'll leave it to the web extension team from here.

Although the "Load Temporary Add-on..." popup claims that you can directly load .zip files it seems like this does not work. You need to unpack the zip first and select the manifest.json file.

Oh my zip archive contains the enclosing folder, therefore this doesn't work.

Attachment #9446173 - Attachment is obsolete: true

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

I agree with Moritz that this doesn't seem like a security bug. Broken, but in raw file:/// form the extension pages will not have any of the powers of a web extension. On the other hand it might then get access to load file:/// urls without having to get permission for it

I don't think the loading of file:/// really works (I think it just shows the wrong think in the url bar) and it also seems that this can only be the local file url to the extension file.

What I managed using my extension (I updated the attachment) is the following:

  1. Go to https://example.org
  2. The extension page is shown
  3. Click on example.org link
  4. Click on example.org link
  5. Click on push state
  6. Click on example.org link
  7. Click on example.org link
  8. Click on push state
  9. Go back
  10. Go back

URL bar now shows https://example.org and page shows error "Access to the file was denied" with the file path to the extension file.

Therefore, while I think this is a bit funny, I could not create a security relevant display issue yet.

Hey Rob, would you mind to take a look into this bug related to DNR API?

Flags: needinfo?(lgreco) → needinfo?(rob)

This is not a DNR-specific issue. A webRequest-initiated redirect has the same issue.

Triggering a navigation to https://example.org/ (which the extension redirects to the moz-extension:-URL) will already result in a bogus history entry, as you can verify with the following code snippet in the global browser console:

{
  let sh = gBrowser.selectedBrowser.browsingContext.sessionHistory;
  for (let i = 0; i < sh.count; i++) {
    let she = sh.getEntryAtIndex(i);
    console.log(`sh ${i}: uri=${she.URI.spec} originalURI=${she.originalURI?.spec} title=${she.title}${sh.index === i ? " CURRENT ENTRY" : ""}`);
  }
}
sh 0: uri=file:///tmp/reproduction_extension/index.html originalURI=https://example.org/ title=Test CURRENT ENTRY

After navigating away to Google.com:

sh 0: uri=file:///tmp/reproduction_extension/index.html originalURI=https://example.org/ title=Test
sh 1: uri=https://www.google.de/ originalURI=https://www.google.de/ title=Google CURRENT ENTRY

Upon navigating back, the URL is still moz-extension://1e0b1315-7eab-46ad-aba1-6932e477c98e/index.html, but the error page shows

Access to the file was denied

The file at /tmp/reproduction_extension/index.html is not readable.

I recall having seen such a bug before, and indeed, this is a duplicate of bug 1826867.

Group: firefox-core-security
Status: UNCONFIRMED → RESOLVED
Closed: 27 days ago
Duplicate of bug: 1826867
Flags: needinfo?(rob)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: