Block remote content when indexing HTML file (#3157)
This commit is contained in:
parent
30624c6aba
commit
2639981dda
4 changed files with 75 additions and 1 deletions
|
@ -62,6 +62,7 @@ const HiddenBrowser = {
|
||||||
* @param {Boolean} [options.allowJavaScript]
|
* @param {Boolean} [options.allowJavaScript]
|
||||||
* @param {Object} [options.docShell] Fields to set on Browser.docShell
|
* @param {Object} [options.docShell] Fields to set on Browser.docShell
|
||||||
* @param {Boolean} [options.requireSuccessfulStatus]
|
* @param {Boolean} [options.requireSuccessfulStatus]
|
||||||
|
* @param {Boolean} [options.blockRemoteResources] Block all remote (non-file:) resources
|
||||||
* @param {Zotero.CookieSandbox} [options.cookieSandbox]
|
* @param {Zotero.CookieSandbox} [options.cookieSandbox]
|
||||||
*/
|
*/
|
||||||
async create(source, options = {}) {
|
async create(source, options = {}) {
|
||||||
|
@ -108,6 +109,10 @@ const HiddenBrowser = {
|
||||||
}, 1000 * 60);
|
}, 1000 * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.blockRemoteResources) {
|
||||||
|
RemoteResourceBlockingObserver.watch(browser);
|
||||||
|
}
|
||||||
|
|
||||||
// Next bit adapted from Mozilla's HeadlessShell.jsm
|
// Next bit adapted from Mozilla's HeadlessShell.jsm
|
||||||
const principal = Services.scriptSecurityManager.getSystemPrincipal();
|
const principal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||||
try {
|
try {
|
||||||
|
@ -229,9 +234,43 @@ const HiddenBrowser = {
|
||||||
destroy(browser) {
|
destroy(browser) {
|
||||||
var frame = browserFrameMap.get(browser);
|
var frame = browserFrameMap.get(browser);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
|
RemoteResourceBlockingObserver.unwatch(browser);
|
||||||
frame.destroy();
|
frame.destroy();
|
||||||
Zotero.debug("Deleted hidden browser");
|
Zotero.debug("Deleted hidden browser");
|
||||||
browserFrameMap.delete(browser);
|
browserFrameMap.delete(browser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const RemoteResourceBlockingObserver = {
|
||||||
|
_observerAdded: false,
|
||||||
|
_ids: new Set(),
|
||||||
|
|
||||||
|
observe(subject) {
|
||||||
|
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
let id = Zotero.platformMajorVersion > 102 ? channel.browserId : channel.topBrowsingContextId;
|
||||||
|
if (this._ids.has(id) && channel.URI.scheme !== 'file') {
|
||||||
|
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch(browser) {
|
||||||
|
let id = Zotero.platformMajorVersion > 102 ? browser.browserId : browser.browsingContext.id;
|
||||||
|
this._ids.add(id);
|
||||||
|
if (!this._observerAdded) {
|
||||||
|
Services.obs.addObserver(this, 'http-on-modify-request');
|
||||||
|
Zotero.debug('RemoteResourceBlockingObserver: Added observer');
|
||||||
|
this._observerAdded = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unwatch(browser) {
|
||||||
|
let id = Zotero.platformMajorVersion > 102 ? browser.browserId : browser.browsingContext.id;
|
||||||
|
this._ids.delete(id);
|
||||||
|
if (this._observerAdded && !this._ids.size) {
|
||||||
|
Services.obs.removeObserver(this, 'http-on-modify-request');
|
||||||
|
Zotero.debug('RemoteResourceBlockingObserver: Removed observer');
|
||||||
|
this._observerAdded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1541,7 +1541,7 @@ Zotero.Fulltext = Zotero.FullText = new function(){
|
||||||
var pageData;
|
var pageData;
|
||||||
try {
|
try {
|
||||||
let url = Zotero.File.pathToFileURI(path);
|
let url = Zotero.File.pathToFileURI(path);
|
||||||
browser = await HiddenBrowser.create(url);
|
browser = await HiddenBrowser.create(url, { blockRemoteResources: true });
|
||||||
pageData = await HiddenBrowser.getPageData(browser, ['characterSet', 'bodyText']);
|
pageData = await HiddenBrowser.getPageData(browser, ['characterSet', 'bodyText']);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
|
@ -8,12 +8,30 @@ describe("HiddenBrowser", function() {
|
||||||
var port = 16213;
|
var port = 16213;
|
||||||
var baseURL = `http://127.0.0.1:${port}/`;
|
var baseURL = `http://127.0.0.1:${port}/`;
|
||||||
|
|
||||||
|
var pngRequested = false;
|
||||||
|
|
||||||
before(function () {
|
before(function () {
|
||||||
Cu.import("resource://zotero-unit/httpd.js");
|
Cu.import("resource://zotero-unit/httpd.js");
|
||||||
httpd = new HttpServer();
|
httpd = new HttpServer();
|
||||||
httpd.start(port);
|
httpd.start(port);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
pngRequested = false;
|
||||||
|
httpd.registerPathHandler(
|
||||||
|
'/remote.png',
|
||||||
|
{
|
||||||
|
handle: function (request, response) {
|
||||||
|
Zotero.debug('Something loaded the image')
|
||||||
|
response.setHeader('Content-Type', 'image/png', false);
|
||||||
|
response.setStatusLine(null, 200, 'OK');
|
||||||
|
response.write('');
|
||||||
|
pngRequested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
await new Promise(resolve => httpd.stop(resolve));
|
await new Promise(resolve => httpd.stop(resolve));
|
||||||
});
|
});
|
||||||
|
@ -22,6 +40,22 @@ describe("HiddenBrowser", function() {
|
||||||
let e = await getPromiseError(HiddenBrowser.create(baseURL + 'nonexistent', { requireSuccessfulStatus: true }));
|
let e = await getPromiseError(HiddenBrowser.create(baseURL + 'nonexistent', { requireSuccessfulStatus: true }));
|
||||||
assert.instanceOf(e, Zotero.HTTP.UnexpectedStatusException);
|
assert.instanceOf(e, Zotero.HTTP.UnexpectedStatusException);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should prevent a remote request with blockRemoteResources", async function () {
|
||||||
|
let path = OS.Path.join(getTestDataDirectory().path, 'test-hidden.html');
|
||||||
|
let browser = await HiddenBrowser.create(path, { blockRemoteResources: true });
|
||||||
|
await HiddenBrowser.getPageData(browser, ['characterSet', 'bodyText']);
|
||||||
|
HiddenBrowser.destroy(browser);
|
||||||
|
assert.isFalse(pngRequested);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow a remote request without blockRemoteResources", async function () {
|
||||||
|
let path = OS.Path.join(getTestDataDirectory().path, 'test-hidden.html');
|
||||||
|
let browser = await HiddenBrowser.create(path, { blockRemoteResources: false });
|
||||||
|
await HiddenBrowser.getPageData(browser, ['characterSet', 'bodyText']);
|
||||||
|
HiddenBrowser.destroy(browser);
|
||||||
|
assert.isTrue(pngRequested);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#getPageData()", function () {
|
describe("#getPageData()", function () {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src="http://127.0.0.1:16213/remote.png">
|
||||||
<p>This is a test.</p>
|
<p>This is a test.</p>
|
||||||
<p style="display: none">This is hidden text.</p>
|
<p style="display: none">This is hidden text.</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue