185 lines
6.5 KiB
Diff
185 lines
6.5 KiB
Diff
From caacc07b2d65aa1ba292681cc4f4f607bf9161dc Mon Sep 17 00:00:00 2001
|
|
From: Gijs Kruitbosch <gijskruitbosch@gmail.com>
|
|
Date: Thu, 24 Mar 2022 14:35:35 +0000 (2022-03-24)
|
|
Subject: [PATCH] CVE-2022-29912
|
|
|
|
---
|
|
browser/actors/AboutReaderParent.jsm | 7 ++
|
|
toolkit/components/reader/AboutReader.jsm | 7 +-
|
|
toolkit/components/reader/ReaderMode.jsm | 82 ++++++++---------------
|
|
3 files changed, 40 insertions(+), 56 deletions(-)
|
|
|
|
diff --git a/browser/actors/AboutReaderParent.jsm b/browser/actors/AboutReaderParent.jsm
|
|
index 20bb1b3be3..9c5fd812f7 100644
|
|
--- a/browser/actors/AboutReaderParent.jsm
|
|
+++ b/browser/actors/AboutReaderParent.jsm
|
|
@@ -155,6 +155,13 @@ class AboutReaderParent extends JSWindowActorParent {
|
|
this.callListeners(message);
|
|
break;
|
|
}
|
|
+
|
|
+ case "RedirectTo": {
|
|
+ gCachedArticles.set(message.data.newURL, message.data.article);
|
|
+ // This is setup as a query so we can navigate the page after we've
|
|
+ // cached the relevant info in the parent.
|
|
+ return true;
|
|
+ }
|
|
|
|
default:
|
|
this.callListeners(message);
|
|
diff --git a/toolkit/components/reader/AboutReader.jsm b/toolkit/components/reader/AboutReader.jsm
|
|
index 4904b525fb..3a1e95411c 100644
|
|
--- a/toolkit/components/reader/AboutReader.jsm
|
|
+++ b/toolkit/components/reader/AboutReader.jsm
|
|
@@ -743,7 +743,12 @@ AboutReader.prototype = {
|
|
try {
|
|
article = await ReaderMode.downloadAndParseDocument(url);
|
|
} catch (e) {
|
|
- if (e && e.newURL) {
|
|
+ if (e?.newURL && this._actor) {
|
|
+ await this._actor.sendQuery("RedirectTo", {
|
|
+ newURL: e.newURL,
|
|
+ article: e.article,
|
|
+ });
|
|
+
|
|
let readerURL = "about:reader?url=" + encodeURIComponent(e.newURL);
|
|
this._win.location.replace(readerURL);
|
|
return;
|
|
diff --git a/toolkit/components/reader/ReaderMode.jsm b/toolkit/components/reader/ReaderMode.jsm
|
|
index 57694c9467..33b80f2c67 100644
|
|
--- a/toolkit/components/reader/ReaderMode.jsm
|
|
+++ b/toolkit/components/reader/ReaderMode.jsm
|
|
@@ -80,7 +80,7 @@ var ReaderMode = {
|
|
*/
|
|
enterReaderMode(docShell, win) {
|
|
let url = win.document.location.href;
|
|
- let readerURL = "about:reader?url=" + encodeURIComponent(url);
|
|
+ let originalURL = this.getOriginalUrl(url);
|
|
let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
|
let sh = webNav.sessionHistory;
|
|
if (webNav.canGoForward) {
|
|
@@ -181,8 +181,8 @@ var ReaderMode = {
|
|
},
|
|
|
|
getOriginalUrlObjectForDisplay(url) {
|
|
- let originalUrl = this.getOriginalUrl(url);
|
|
- if (originalUrl) {
|
|
+ let originalUrl = this.getOriginalUrl(url);
|
|
+ if (originalUrl) {
|
|
let uriObj;
|
|
try {
|
|
uriObj = Services.uriFixup.createFixupURI(
|
|
@@ -229,10 +229,11 @@ var ReaderMode = {
|
|
* @resolves JS object representing the article, or null if no article is found.
|
|
*/
|
|
async downloadAndParseDocument(url) {
|
|
- let doc = await this._downloadDocument(url);
|
|
- if (!doc) {
|
|
+ let result = await this._downloadDocument(url, docContentType);
|
|
+ if (!result?.doc) {
|
|
return null;
|
|
}
|
|
+ let { doc, newURL } = result;
|
|
if (
|
|
!Readerable.shouldCheckUri(doc.documentURIObject) ||
|
|
!Readerable.shouldCheckUri(doc.baseURIObject, true)
|
|
@@ -241,7 +242,14 @@ var ReaderMode = {
|
|
return null;
|
|
}
|
|
|
|
- return this._readerParse(doc);
|
|
+ let article = await this._readerParse(doc);
|
|
+ // If we have to redirect, reject to the caller with the parsed article,
|
|
+ // so we can update the URL before displaying it.
|
|
+ if (newURL) {
|
|
+ return Promise.reject({ newURL, article });
|
|
+ }
|
|
+ // Otherwise, we can just continue with the article.
|
|
+ return article;
|
|
},
|
|
|
|
_downloadDocument(url) {
|
|
@@ -276,49 +284,7 @@ var ReaderMode = {
|
|
histogram.add(DOWNLOAD_ERROR_NO_DOC);
|
|
return;
|
|
}
|
|
-
|
|
- // Manually follow a meta refresh tag if one exists.
|
|
- let meta = doc.querySelector("meta[http-equiv=refresh]");
|
|
- if (meta) {
|
|
- let content = meta.getAttribute("content");
|
|
- if (content) {
|
|
- let urlIndex = content.toUpperCase().indexOf("URL=");
|
|
- if (urlIndex > -1) {
|
|
- let baseURI = Services.io.newURI(url);
|
|
- let newURI = Services.io.newURI(
|
|
- content.substring(urlIndex + 4),
|
|
- null,
|
|
- baseURI
|
|
- );
|
|
- let newURL = newURI.spec;
|
|
- let ssm = Services.scriptSecurityManager;
|
|
- let flags =
|
|
- ssm.LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
|
|
- ssm.DISALLOW_INHERIT_PRINCIPAL;
|
|
- try {
|
|
- ssm.checkLoadURIStrWithPrincipal(
|
|
- doc.nodePrincipal,
|
|
- newURL,
|
|
- flags
|
|
- );
|
|
- } catch (ex) {
|
|
- let errorMsg =
|
|
- "Reader mode disallowed meta refresh (reason: " + ex + ").";
|
|
-
|
|
- if (Services.prefs.getBoolPref("reader.errors.includeURLs")) {
|
|
- errorMsg += " Refresh target URI: '" + newURL + "'.";
|
|
- }
|
|
- reject(errorMsg);
|
|
- return;
|
|
- }
|
|
- // Otherwise, pass an object indicating our new URL:
|
|
- if (!baseURI.equalsExceptRef(newURI)) {
|
|
- reject({ newURL });
|
|
- return;
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
+
|
|
let responseURL = xhr.responseURL;
|
|
let givenURL = url;
|
|
// Convert these to real URIs to make sure the escaping (or lack
|
|
@@ -332,16 +298,22 @@ var ReaderMode = {
|
|
givenURL = Services.io.newURI(givenURL).specIgnoringRef;
|
|
} catch (ex) {
|
|
/* Ignore errors - we'll use what we had before */
|
|
+ }
|
|
+ if (xhr.responseType != "document") {
|
|
+ let initialText = doc;
|
|
+ let parser = new DOMParser();
|
|
+ doc = parser.parseFromString(`<pre></pre>`, "text/html");
|
|
+ doc.querySelector("pre").textContent = initialText;
|
|
}
|
|
|
|
+ // We treat redirects as download successes here:
|
|
+ histogram.add(DOWNLOAD_SUCCESS);
|
|
+ let result = { doc };
|
|
if (responseURL != givenURL) {
|
|
- // We were redirected without a meta refresh tag.
|
|
- // Force redirect to the correct place:
|
|
- reject({ newURL: xhr.responseURL });
|
|
- return;
|
|
+ result.newURL = xhr.responseURL;
|
|
}
|
|
- resolve(doc);
|
|
- histogram.add(DOWNLOAD_SUCCESS);
|
|
+
|
|
+ resolve(result);
|
|
};
|
|
xhr.send();
|
|
});
|
|
--
|
|
2.33.0
|
|
|