Electron:仅使用 startsWith if 语句 "protection" 公开 ipcRenderer 方法是否安全?

Electron: Is it safe to expose ipcRenderer methods with only a startsWith if statement "protection"?

我有一个电子应用程序,我正在使用 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 的源代码中看到了这一点,但是我也阅读了一些使用字符串数组来验证通道的解决方案。如果它是安全的,为什么我不能在不检查频道是否以某个随机名称开始的情况下直接公开它?有没有不能暴露的默认频道?

是的,检查您的频道名称是否仅以“特定”字符串开头是绝对安全的。如果它是一个“随机”字符串,那么人们可能会争辩说,甚至没有理由担心实施“频道命名”系统。

您是正确的,因为您可以不使用频道名称而公开 ipcRenderer 方法。这本身不是安全问题。

EG:

// 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);
        }
    }
};

如果您在创建 window 期间设置了 nodeIntegration: truecontextIsolation: false,则存在安全隐患。这将允许任何可以在您的渲染中 运行 Javascript 的人(例如:如果 DevTools 仍然可以访问)访问主线程并可能调用各种 Node.js 和用户定义的函数。例如:使用任何主线程 hard-coded API 键访问在线数据库或 API。

另一个安全问题是,如果您将特定的电子 API 添加到您的 preload.js 脚本中,根本不应该从渲染线程访问它。

至于“无法公开的默认通道”,通道本身不是问题,如果可以从渲染线程访问,任何底层(公开的)函数都可能带来安全问题。

在您的 preload.js 文件中实施“频道命名”系统只是允许一种更简单的方式来跟踪和管理 IPC 事件,就像处理 Node.js 事件一样。它并不适合所有人,也绝不是强制/要求有一个使用“频道命名”系统的 preload.js 脚本。纯属个人喜好。