Electron:只使用startsWith if语句“protection”公开ipcRenderer方法安全吗?

pgx2nnw8  于 2023-04-03  发布在  Electron
关注(0)|答案(1)|浏览(143)

我有一个电子应用程序,我使用contextBridge.exposeInMainWorld来公开一些ipcRenderer方法,如.on.removeListener.invoke,这些方法通过使用if语句来检查“通道”是否有效。
使用以下代码:

const validateIPC = (channel) => {
  if (!channel || !channel.startsWith("myapp:")) 
    return false;
 
  return true;
};

contextBridge.exposeInMainWorld("electron", {
ipcRenderer: {
    on(channel, listener) {
      if (validateIPC(channel)) {
        ipcRenderer.on(channel, (evt, message) => {
          listener(evt, message);
        });
      }
    },
    removeListener(channel, listener) {
      if (validateIPC(channel)) {
        ipcRenderer.removeListener(channel, (evt, message) => {
          listener(evt, message);
        });
      }
    },
    invoke(channel, data) {
      if (validateIPC(channel)) {
        return ipcRenderer.invoke(channel, data);
      }
    },
  },
};

只检查通道是否以随机字符串开头安全吗?我在github上的vscode源代码中看到了这个问题,但是我也读到了一些使用字符串数组来验证通道的解决方案。如果是安全的,为什么我不能直接暴露它而不检查通道是否以随机名称开头?有没有默认的通道不能暴露?

c7rzv4ha

c7rzv4ha1#

是的,检查你的频道名称是否仅以“特定”字符串开头是绝对安全的。如果它是一个“随机”字符串,那么人们可能会争辩说,甚至没有理由担心实现“频道命名”系统。
您是正确的,因为您可以只公开ipcRenderer方法而不使用通道名,这本身并不是一个安全问题。
例如:

// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld("electron", {
    ipcRenderer: {
        on(channel, listener) {
            ipcRenderer.on(channel, (evt, message) => {
                listener(evt, message);
            });
        },
        removeListener(channel, listener) {
            ipcRenderer.removeListener(channel, (evt, message) => {
                listener(evt, message);
            });
        },
        invoke(channel, data) {
            return ipcRenderer.invoke(channel, data);
        }
    }
};

如果你在创建窗口的时候设置了nodeIntegration: truecontextIsolation: false,这会让任何人都可以在你的渲染中运行Javascript(例如:如果DevTools仍然可以访问)来访问主线程,并可能调用各种Node.js和用户定义的函数。例如:使用任何主线程硬编码API密钥访问在线数据库或API。
另一个安全问题是,如果您将特定的电子API添加到您的preload.js脚本中,则根本不应该从渲染线程访问。
至于“不能暴露的默认通道”,通道本身不是问题,如果从渲染线程可访问,则任何底层(暴露的)函数都可能引起安全问题。
在您的preload.js文件中实现“通道命名”系统只是允许更轻松地跟踪和管理IPC事件,就像Node.js事件一样。它并不适合每个人,也不是强制/要求使用“通道命名”系统的preload.js脚本。这纯粹是个人喜好。

相关问题