I'm the author of the template, let me offer some background knowledge you might find helpful. Disclaimer: I'm not a security researcher, but this is scraped from multiple sources.
ContextBridge is important because it offers protection against passing values into the renderer process based off the old way.
Old way
const {
ipcRenderer
} = require("electron");
window.send = function(channel, data){
// whitelist channels
let validChannels = ["toMain"];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
};
window.recieve = function(channel, func){
let validChannels = ["fromMain"];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
};
This code is vulnerable to the client opening the dev tools, and modifying the function definition of window.send
and window.recieve
. The client can then start to ping your ipcMain in your main.js script and then possibly do some damage because they could get around your whitelisting ipc channels in the preload js. This assumes you are whitelisting in your main.js too, but I've seen plenty of examples that are not and would be vulnerable to such an attack.
From the docs:
Function values are proxied to the other context and all other values are copied and frozen. Any data / primitives sent in the API object become immutable and updates on either side of the bridge do not result in an update on the other side.
In other words, because we use contextBridge.exposeInMainWorld
, our renderer process cannot modify the definition of the functions we expose, protecting us from a possible security attack vector.
New way
const {
contextBridge,
ipcRenderer
} = require("electron");
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
"api", {
send: (channel, data) => {
// whitelist channels
let validChannels = ["toMain"];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel, func) => {
let validChannels = ["fromMain"];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
}
}
);
Source
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…