【发布时间】:2020-01-09 06:36:54
【问题描述】:
我想使用 BrowserView 在 Electron 中加载外部网页。它的 API 与 BrowserWindow 几乎相同。
const currentWindow = remote.getCurrentWindow();
const view = new remote.BrowserView({
webPreferences: {
// contextIsolation: true,
partition: 'my-view-partition',
enableRemoteModule: false,
nodeIntegration: false,
preload: `${__dirname}/preload.js`,
sandbox: true,
},
});
view.setAutoResize({ width: true, height: true });
view.webContents.loadURL('http://localhost:3000');
在我的preload.js 文件中,我只是将一个变量附加到全局对象。
process.once('loaded', () => {
global.baz = 'qux';
});
在localhost:3000 上运行的应用是一个 React 应用,它引用如下值:
const sharedString = global.baz || 'Not found';
问题是我必须在创建BrowserView 时注释掉设置contextIsolation: true。这暴露了一个安全漏洞。
是否有可能(一种方式 - 从 Electron 到网页)将变量注入 BrowserView(或 BrowserWindow),同时仍然使用 contextIsolation 使 Electron 环境与对全局环境所做的任何更改隔离通过加载的内容?
更新: 一种可能的方法是拦截网络协议,但我不确定这一点????
app.on('ready', () => {
const { protocol } = session.fromPartition('my-partition')
protocol.interceptBufferProtocol('https', (req, callback) => {
if (req.uploadData) {
// How to handle file uploads?
callback()
return
}
// This is electron.net, docs: https://electronjs.org/docs/api/net
net
.request(req)
.on('response', (res) => {
const chunks = []
res.on('data', (chunk) => {
chunks.push(Buffer.from(chunk))
})
res.on('end', () => {
const blob = Buffer.concat(chunks)
const type = res.headers['content-type'] || []
if (type.includes('text/html') && blob.includes('<head>')) {
// FIXME?
const pos = blob.indexOf('<head>')
// inject contains the Buffer with the injected HTML script
callback(Buffer.concat([blob.slice(0, pos), inject, blob.slice(pos)]))
} else {
callback(blob)
}
})
})
.on('error', (err) => {
console.error('error', err)
callback()
})
.end()
})
})
【问题讨论】:
-
如果您的全局变量是一个简单的字符串,为什么不将它作为 url 的查询参数传递,例如:
view.webContents.loadURL('http://localhost:3000?baz=qux');。在您的反应应用程序中,您可以解析查询参数。 -
@VaibhavVishal 不是。我想举一个简单的例子,但我需要注入的是一个 Web3 提供者。
-
@J.Hesters 您的 React 应用程序是否已经包含
web3.js库(如果我正确理解您的情况)?然后你可以传入一个提供者 URL 字符串。您将无法将库作为全局变量从电子传递到启用 contextIsolation 的页面。另外我不确定,您的代码 sn-pprotocol.interceptBufferProtocol与您的案例有什么关系(文件上传?应该拦截什么 https 请求?)。看起来有点像 XY 问题,这可能更容易完成。也许您可以详细说明您的问题。 -
如果您能够调整 Web 应用程序构建:另一种方法是提供 React Web 应用程序的电子特定版本,它通过添加/捆绑的 web3 功能扩展您的基本 Web 版本。这个增强版本可以包含在您的 Electron 构建中,而 Web 版本保持不变。
标签: javascript reactjs security electron