ma1 pushed to branch tor-browser-115.2.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits: 255203a3 by cypherpunks1 at 2023-08-21T19:11:56+00:00 fixup! Bug 3455: Add DomainIsolator, for isolating circuit by domain.
Bug 40175: Use first-party isolation on reader view
- - - - - 3f596978 by cypherpunks1 at 2023-08-21T19:11:56+00:00 fixup! Bug 41600: Add a tor circuit display panel.
Bug 40175: Support circuit display on about:reader
- - - - - 5073f134 by cypherpunks1 at 2023-08-21T19:11:56+00:00 Bug 40175: Add origin attributes to about:reader top-level requests
- - - - -
4 changed files:
- browser/components/torcircuit/content/torCircuitPanel.js - toolkit/components/reader/AboutReader.sys.mjs - toolkit/components/reader/ReaderMode.sys.mjs - toolkit/components/tor-launcher/TorDomainIsolator.sys.mjs
Changes:
===================================== browser/components/torcircuit/content/torCircuitPanel.js ===================================== @@ -276,7 +276,18 @@ var gTorCircuitPanel = { // will match up with the domain. // In contrast, documentURI corresponds to the shown page. E.g. it could // point to "about:certerror". - const scheme = browser.currentURI?.scheme; + let scheme = browser.currentURI?.scheme; + if (scheme === "about" && browser.currentURI?.filePath === "reader") { + const searchParams = new URLSearchParams(browser.currentURI.query); + if (searchParams.has("url")) { + try { + const uri = Services.io.newURI(searchParams.get("url")); + scheme = uri.scheme; + } catch (err) { + this._log.error(err); + } + } + }
if ( this._currentBrowserData &&
===================================== toolkit/components/reader/AboutReader.sys.mjs ===================================== @@ -788,6 +788,7 @@ AboutReader.prototype = { try { article = await ReaderMode.downloadAndParseDocument( url, + { ...this._doc.nodePrincipal?.originAttributes }, docContentType ); } catch (e) {
===================================== toolkit/components/reader/ReaderMode.sys.mjs ===================================== @@ -231,11 +231,12 @@ export var ReaderMode = { * Downloads and parses a document from a URL. * * @param url URL to download and parse. + * @param attrs OriginAttributes to use for the request. * @return {Promise} * @resolves JS object representing the article, or null if no article is found. */ - async downloadAndParseDocument(url, docContentType = "document") { - let result = await this._downloadDocument(url, docContentType); + async downloadAndParseDocument(url, attrs = {}, docContentType = "document") { + let result = await this._downloadDocument(url, attrs, docContentType); if (!result?.doc) { return null; } @@ -258,9 +259,11 @@ export var ReaderMode = { return article; },
- _downloadDocument(url, docContentType = "document") { + _downloadDocument(url, attrs = {}, docContentType = "document") { + let uri; try { - if (!lazy.Readerable.shouldCheckUri(Services.io.newURI(url))) { + uri = Services.io.newURI(url); + if (!lazy.Readerable.shouldCheckUri(uri)) { return null; } } catch (ex) { @@ -272,9 +275,15 @@ export var ReaderMode = { let histogram = Services.telemetry.getHistogramById( "READER_MODE_DOWNLOAD_RESULT" ); + try { + attrs.firstPartyDomain = Services.eTLD.getSchemelessSite(uri); + } catch (e) { + console.error("Failed to get first party domain for about:reader", e); + } return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open("GET", url, true); + xhr.setOriginAttributes(attrs); xhr.onerror = evt => reject(evt.error); xhr.responseType = docContentType === "text/plain" ? "text" : "document"; xhr.onload = evt => {
===================================== toolkit/components/tor-launcher/TorDomainIsolator.sys.mjs ===================================== @@ -300,6 +300,17 @@ class TorDomainIsolatorImpl { const channel = aChannel.QueryInterface(Ci.nsIChannel); let firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain; const userContextId = channel.loadInfo.originAttributes.userContextId; + const loadingPrincipalURI = channel.loadInfo.loadingPrincipal?.URI; + if (loadingPrincipalURI?.spec.startsWith("about:reader")) { + try { + const searchParams = new URLSearchParams(loadingPrincipalURI.query); + if (searchParams.has("url")) { + firstPartyDomain = Services.eTLD.getSchemelessSite(Services.io.newURI(searchParams.get("url"))); + } + } catch (e) { + logger.error("Failed to get first party domain for about:reader", e); + } + } if (!firstPartyDomain) { firstPartyDomain = CATCHALL_DOMAIN; if (Date.now() - this.#catchallDirtySince > CATCHALL_MAX_LIFETIME) { @@ -629,36 +640,43 @@ class TorDomainIsolatorImpl { function getDomainForBrowser(browser) { let fpd = browser.contentPrincipal.originAttributes.firstPartyDomain;
- // Bug 31562: For neterror or certerror, get the original URL from - // browser.currentURI and use it to calculate the firstPartyDomain. - const knownErrors = [ - "about:neterror", - "about:certerror", - "about:httpsonlyerror", - ]; const { documentURI } = browser; - if ( - documentURI && - documentURI.schemeIs("about") && - knownErrors.some(x => documentURI.spec.startsWith(x)) - ) { - const knownSchemes = ["http", "https"]; - const currentURI = browser.currentURI; - if (currentURI && knownSchemes.some(x => currentURI.schemeIs(x))) { + if (documentURI && documentURI.schemeIs("about")) { + // Bug 31562: For neterror or certerror, get the original URL from + // browser.currentURI and use it to calculate the firstPartyDomain. + const knownErrors = [ + "about:neterror", + "about:certerror", + "about:httpsonlyerror", + ]; + if (knownErrors.some(x => documentURI.spec.startsWith(x))) { + const knownSchemes = ["http", "https"]; + const currentURI = browser.currentURI; + if (currentURI && knownSchemes.some(x => currentURI.schemeIs(x))) { + try { + fpd = Services.eTLD.getBaseDomainFromHost(currentURI.host); + } catch (e) { + if ( + e.result === Cr.NS_ERROR_HOST_IS_IP_ADDRESS || + e.result === Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS + ) { + fpd = currentURI.host; + } else { + logger.error( + `Failed to get first party domain for host ${currentURI.host}`, + e + ); + } + } + } + } else if (documentURI.spec.startsWith("about:reader")) { try { - fpd = Services.eTLD.getBaseDomainFromHost(currentURI.host); - } catch (e) { - if ( - e.result === Cr.NS_ERROR_HOST_IS_IP_ADDRESS || - e.result === Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS - ) { - fpd = currentURI.host; - } else { - logger.error( - `Failed to get first party domain for host ${currentURI.host}`, - e - ); + const searchParams = new URLSearchParams(documentURI.query); + if (searchParams.has("url")) { + fpd = Services.eTLD.getSchemelessSite(Services.io.newURI(searchParams.get("url"))); } + } catch (e) { + logger.error("Failed to get first party domain for about:reader", e); } } }
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/968d392...