feat: add ContextBridgeMutability feature (#27348)

This commit is contained in:
Nikita Kot 2021-03-22 18:16:35 +01:00 committed by GitHub
parent fa320eeb90
commit e99893df22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 0 deletions

View file

@ -11,6 +11,7 @@
#include <utility>
#include <vector>
#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "content/public/renderer/render_frame.h"
@ -25,6 +26,12 @@
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
namespace features {
const base::Feature kContextBridgeMutability{"ContextBridgeMutability",
base::FEATURE_DISABLED_BY_DEFAULT};
}
namespace electron {
namespace api {
@ -554,6 +561,12 @@ void ExposeAPIInMainWorld(v8::Isolate* isolate,
if (maybe_proxy.IsEmpty())
return;
auto proxy = maybe_proxy.ToLocalChecked();
if (base::FeatureList::IsEnabled(features::kContextBridgeMutability)) {
global.Set(key, proxy);
return;
}
if (proxy->IsObject() && !proxy->IsTypedArray() &&
!DeepFreeze(v8::Local<v8::Object>::Cast(proxy), main_context))
return;

View file

@ -5,6 +5,7 @@ import * as fs from 'fs-extra';
import * as http from 'http';
import * as os from 'os';
import * as path from 'path';
import * as cp from 'child_process';
import { closeWindow } from './window-helpers';
import { emittedOnce } from './events-helpers';
@ -1165,3 +1166,31 @@ describe('contextBridge', () => {
generateTests(true);
generateTests(false);
});
describe('ContextBridgeMutability', () => {
it('should not make properties unwriteable and read-only if ContextBridgeMutability is on', async () => {
const appPath = path.join(fixturesPath, 'context-bridge-mutability');
const appProcess = cp.spawn(process.execPath, ['--enable-logging', '--enable-features=ContextBridgeMutability', appPath]);
let output = '';
appProcess.stdout.on('data', data => { output += data; });
await emittedOnce(appProcess, 'exit');
expect(output).to.include('some-modified-text');
expect(output).to.include('obj-modified-prop');
expect(output).to.include('1,2,5,3,4');
});
it('should make properties unwriteable and read-only if ContextBridgeMutability is off', async () => {
const appPath = path.join(fixturesPath, 'context-bridge-mutability');
const appProcess = cp.spawn(process.execPath, ['--enable-logging', appPath]);
let output = '';
appProcess.stdout.on('data', data => { output += data; });
await emittedOnce(appProcess, 'exit');
expect(output).to.include('some-text');
expect(output).to.include('obj-prop');
expect(output).to.include('1,2,3,4');
});
});

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<body>
<script>
try {
window.str = 'some-modified-text';
window.obj.prop = 'obj-modified-prop';
window.arr.splice(2, 0, 5);
} catch (e) { }
console.log(window.str);
console.log(window.obj.prop);
console.log(window.arr);
</script>
</body>
</html>

View file

@ -0,0 +1,20 @@
const { app, BrowserWindow } = require('electron');
const path = require('path');
let win;
app.whenReady().then(function () {
win = new BrowserWindow({
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
win.loadFile('index.html');
win.webContents.on('console-message', (event, level, message) => {
console.log(message);
});
win.webContents.on('did-finish-load', () => app.quit());
});

View file

@ -0,0 +1,4 @@
{
"name": "context-bridge-mutability",
"main": "main.js"
}

View file

@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('str', 'some-text');
contextBridge.exposeInMainWorld('obj', { prop: 'obj-prop' });
contextBridge.exposeInMainWorld('arr', [1, 2, 3, 4]);