Bug 1759786 - Send tab should not send or receive file:// uris r=markh

Differential Revision: https://phabricator.services.mozilla.com/D142746
This commit is contained in:
Sammy Khamis 2022-04-04 23:25:59 +00:00
Родитель 9cc43cb992
Коммит 631c25c933
4 изменённых файлов: 102 добавлений и 12 удалений

Просмотреть файл

@ -30,6 +30,17 @@ XPCOMUtils.defineLazyModuleGetters(this, {
CryptoWrapper: "resource://services-sync/record.js", CryptoWrapper: "resource://services-sync/record.js",
}); });
XPCOMUtils.defineLazyPreferenceGetter(
this,
"INVALID_SHAREABLE_SCHEMES",
"services.sync.engine.tabs.filteredSchemes",
"",
null,
val => {
return new Set(val.split("|"));
}
);
class FxAccountsCommands { class FxAccountsCommands {
constructor(fxAccountsInternal) { constructor(fxAccountsInternal) {
this._fxai = fxAccountsInternal; this._fxai = fxAccountsInternal;
@ -199,6 +210,13 @@ class FxAccountsCommands {
sender ? sender.name : "Unknown device" sender ? sender.name : "Unknown device"
}.` }.`
); );
// This should eventually be rare to hit as all platforms will be using the same
// scheme filter list, but we have this here in the case other platforms
// haven't caught up and/or trying to send invalid uris using older versions
const scheme = Services.io.newURI(uri).scheme;
if (INVALID_SHAREABLE_SCHEMES.has(scheme)) {
throw new Error("Invalid scheme found for received URI.");
}
tabsReceived.push({ title, uri, sender }); tabsReceived.push({ title, uri, sender });
} catch (e) { } catch (e) {
log.error(`Error while handling incoming Send Tab payload.`, e); log.error(`Error while handling incoming Send Tab payload.`, e);
@ -209,9 +227,13 @@ class FxAccountsCommands {
} }
} }
if (tabsReceived.length) { if (tabsReceived.length) {
Observers.notify("fxaccounts:commands:open-uri", tabsReceived); this._notifyFxATabsReceived(tabsReceived);
} }
} }
_notifyFxATabsReceived(tabsReceived) {
Observers.notify("fxaccounts:commands:open-uri", tabsReceived);
}
} }
/** /**

Просмотреть файл

@ -392,7 +392,7 @@ add_task(async function test_commands_handleCommands() {
commands.sendTab.handle = (sender, data, reason) => { commands.sendTab.handle = (sender, data, reason) => {
return { return {
title: "testTitle", title: "testTitle",
uri: "testURI", uri: "https://testURI",
}; };
}; };
commands._fxai.device = { commands._fxai.device = {
@ -408,6 +408,57 @@ add_task(async function test_commands_handleCommands() {
.expects("_getReason") .expects("_getReason")
.once() .once()
.withExactArgs(pushIndexReceived, remoteMessageIndex); .withExactArgs(pushIndexReceived, remoteMessageIndex);
mockCommands.expects("_notifyFxATabsReceived").once();
await commands._handleCommands(remoteMessages, pushIndexReceived);
mockCommands.verify();
});
add_task(async function test_commands_handleCommands_invalid_tab() {
// This test ensures that `_getReason` is being called by
// `_handleCommands` with the expected parameters.
const pushIndexReceived = 12;
const senderID = "6d09f6c4-89b2-41b3-a0ac-e4c2502b5485";
const remoteMessageIndex = 8;
const remoteMessages = [
{
index: remoteMessageIndex,
data: {
command: COMMAND_SENDTAB,
payload: {
encrypted: {},
},
sender: senderID,
},
},
];
const fxAccounts = {
async withCurrentAccountState(cb) {
await cb({});
},
};
const commands = new FxAccountsCommands(fxAccounts);
commands.sendTab.handle = (sender, data, reason) => {
return {
title: "badUriTab",
uri: "file://path/to/pdf",
};
};
commands._fxai.device = {
refreshDeviceList: () => {},
recentDeviceList: [
{
id: senderID,
},
],
};
const mockCommands = sinon.mock(commands);
mockCommands
.expects("_getReason")
.once()
.withExactArgs(pushIndexReceived, remoteMessageIndex);
// We shouldn't have tried to open a tab with an invalid uri
mockCommands.expects("_notifyFxATabsReceived").never();
await commands._handleCommands(remoteMessages, pushIndexReceived); await commands._handleCommands(remoteMessages, pushIndexReceived);
mockCommands.verify(); mockCommands.verify();

Просмотреть файл

@ -20,6 +20,17 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/Region.jsm" "resource://gre/modules/Region.jsm"
); );
XPCOMUtils.defineLazyPreferenceGetter(
this,
"INVALID_SHAREABLE_SCHEMES",
"services.sync.engine.tabs.filteredSchemes",
"",
null,
val => {
return new Set(val.split("|"));
}
);
function stringPrefToSet(prefVal) { function stringPrefToSet(prefVal) {
return new Set( return new Set(
prefVal prefVal
@ -147,16 +158,9 @@ var BrowserUtils = {
if (url.spec.length > 65535) { if (url.spec.length > 65535) {
return false; return false;
} }
// Use the same preference as synced tabs to disable what kind
let scheme = url.scheme; // of tabs we can send to another device
return !INVALID_SHAREABLE_SCHEMES.has(url.scheme);
return !(
"about" == scheme ||
"resource" == scheme ||
"chrome" == scheme ||
"blob" == scheme ||
"moz-extension" == scheme
);
}, },
/** /**

Просмотреть файл

@ -186,3 +186,16 @@ add_task(async function test_shouldShowFocusPromo() {
Preferences.resetBranch("browser.promo.focus"); Preferences.resetBranch("browser.promo.focus");
}); });
add_task(function test_isShareableURL() {
// Empty shouldn't be sendable
Assert.ok(!BrowserUtils.isShareableURL(""));
// Valid
Assert.ok(
BrowserUtils.isShareableURL(Services.io.newURI("https://mozilla.org"))
);
// Invalid
Assert.ok(
!BrowserUtils.isShareableURL(Services.io.newURI("file://path/to/pdf.pdf"))
);
});