javascript - Electron:如何安全地将全局变量注入(inject) BrowserWindow/BrowserView?

标签 javascript reactjs security electron

我想使用 BrowserView 在 Electron 中加载外部网页。它具有与 BrowserWindow 几乎相同的 API。

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 到网页)将变量注入(inject) BrowserView(或 BrowserWindow),同时仍然使用 contextIsolation 使 Electron 环境与加载内容对全局环境所做的任何更改隔离?

更新: 一种可能的方法是拦截网络协议(protocol),但我不确定这个 🤔

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()
  })
})

最佳答案

在进行一些挖掘之后,我发现了一些针对 Electron 的拉取请求,其中详细说明了您遇到的问题。 first描述了一个与您描述的问题非常相似的可重现示例。

Expected Behavior

https://electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content A preload script should be able to attach anything to the window or document with contextIsolation: true.

Actual behavior

Anything attached to the window in the preload.js just disappears in the renderer.

最后的评论似乎解释了预期的行为不再有效

It was actually possible until recently, a PR with Isolated Worlds has changed the behavior.

second让用户建议他们发现的解决方案:

After many days of research and fiddling with the IPC, I've concluded that the best way is to go the protocol route.

我查看了 BrowserWindow 的文档和 BrowserView以及 example这显示了您想要的行为,但这些 PR 表明这不再可能(沿着这条路线)。

可能的解决方案

查看文档,您从 view.webContents 获得的 webContents 对象具有函数 executeJavaScript , 因此您可以尝试以下设置全局变量。

...
view.setAutoResize({ width: true, height: true });
view.webContents.loadURL('http://localhost:3000');
view.webContents.executeJavaScript("global.baz = 'qux';");
...

关于javascript - Electron:如何安全地将全局变量注入(inject) BrowserWindow/BrowserView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57821060/

相关文章:

json - 如何将 getJSON 数据绑定(bind)到 ReactJS 状态

javascript - 关于没有中间件的 Redux Async (redux-thunk, redux-saga...)

spring-boot - 应用程序发起调用时如何处理微服务之间的身份验证

javascript - Node.js 只使用数组中的最后一项

php - 如何避免在 Javascript 和 PHP 中重复公式?

javascript - IE 选择和范围问题

javascript - 像按钮一样 react 切换

ruby-on-rails - Rails PDF 上传恶意内容漏洞

ios - 通过 iOS 深层链接传递身份验证 token 是否安全?

javascript - jquery灯开关设置起始状态