fix: disallow loading extensions in temp sessions (#22090)

* fix: disallow loading extensions in temp sessions

* docs
This commit is contained in:
Jeremy Apthorp 2020-02-10 08:28:03 -08:00 коммит произвёл GitHub
Родитель c2cd588e70
Коммит af631f8204
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 25 добавлений и 8 удалений

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

@ -28,6 +28,9 @@ session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
Loaded extensions will not be automatically remembered across exits; if you do Loaded extensions will not be automatically remembered across exits; if you do
not call `loadExtension` when the app runs, the extension will not be loaded. not call `loadExtension` when the app runs, the extension will not be loaded.
Note that loading extensions is only supported in persistent sessions.
Attempting to load an extension into an in-memory session will throw an error.
See the [`session`](session.md) documentation for more information about See the [`session`](session.md) documentation for more information about
loading, unloading, and querying active extensions. loading, unloading, and querying active extensions.

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

@ -507,6 +507,8 @@ requests an API that Electron does not support) then they will be logged to the
console. console.
Note that Electron does not support the full range of Chrome extensions APIs. Note that Electron does not support the full range of Chrome extensions APIs.
See [Supported Extensions APIs](extensions.md#supported-extensions-apis) for
more details on what is supported.
Note that in previous versions of Electron, extensions that were loaded would Note that in previous versions of Electron, extensions that were loaded would
be remembered for future runs of the application. This is no longer the case: be remembered for future runs of the application. This is no longer the case:
@ -529,6 +531,9 @@ This API does not support loading packed (.crx) extensions.
**Note:** This API cannot be called before the `ready` event of the `app` module **Note:** This API cannot be called before the `ready` event of the `app` module
is emitted. is emitted.
**Note:** Loading extensions into in-memory (non-persistent) sessions is not
supported and will throw an error.
#### `ses.removeExtension(extensionId)` #### `ses.removeExtension(extensionId)`
* `extensionId` String - ID of extension to remove * `extensionId` String - ID of extension to remove

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

@ -613,6 +613,11 @@ v8::Local<v8::Promise> Session::LoadExtension(
const base::FilePath& extension_path) { const base::FilePath& extension_path) {
gin_helper::Promise<const extensions::Extension*> promise(isolate()); gin_helper::Promise<const extensions::Extension*> promise(isolate());
v8::Local<v8::Promise> handle = promise.GetHandle(); v8::Local<v8::Promise> handle = promise.GetHandle();
if (browser_context()->IsOffTheRecord()) {
promise.RejectWithErrorMessage(
"Extensions cannot be loaded in a temporary session");
return handle;
}
auto* extension_system = static_cast<extensions::ElectronExtensionSystem*>( auto* extension_system = static_cast<extensions::ElectronExtensionSystem*>(
extensions::ExtensionSystem::Get(browser_context())); extensions::ExtensionSystem::Get(browser_context()));

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

@ -24,8 +24,13 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
after(() => { after(() => {
server.close() server.close()
}) })
afterEach(closeAllWindows) afterEach(closeAllWindows)
afterEach(() => {
session.defaultSession.getAllExtensions().forEach((e: any) => {
session.defaultSession.removeExtension(e.id)
})
})
it('loads an extension', async () => { it('loads an extension', async () => {
// NB. we have to use a persist: session (i.e. non-OTR) because the // NB. we have to use a persist: session (i.e. non-OTR) because the
// extension registry is redirected to the main session. so installing an // extension registry is redirected to the main session. so installing an
@ -73,13 +78,18 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
it('confines an extension to the session it was loaded in', async () => { it('confines an extension to the session it was loaded in', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`) const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg')) await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const w = new BrowserWindow({ show: false }) // not in the session const w = new BrowserWindow({ show: false }) // not in the session
await w.loadURL(url) await w.loadURL(url)
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor') const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
expect(bg).to.equal('') expect(bg).to.equal('')
}) })
it('loading an extension in a temporary session throws an error', async () => {
const customSession = session.fromPartition(require('uuid').v4())
await expect(customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))).to.eventually.be.rejectedWith('Extensions cannot be loaded in a temporary session')
})
describe('chrome.runtime', () => { describe('chrome.runtime', () => {
let content: any let content: any
before(async () => { before(async () => {
@ -239,12 +249,6 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
}) })
describe('deprecation shims', () => { describe('deprecation shims', () => {
afterEach(() => {
session.defaultSession.getAllExtensions().forEach((e: any) => {
session.defaultSession.removeExtension(e.id)
})
})
it('loads an extension through BrowserWindow.addExtension', async () => { it('loads an extension through BrowserWindow.addExtension', async () => {
BrowserWindow.addExtension(path.join(fixtures, 'extensions', 'red-bg')) BrowserWindow.addExtension(path.join(fixtures, 'extensions', 'red-bg'))
const w = new BrowserWindow({ show: false }) const w = new BrowserWindow({ show: false })