Giter VIP home page Giter VIP logo

Comments (4)

briosheje avatar briosheje commented on June 12, 2024 1

Thanks @briosheje i might try that. If you know, can you elaborate on the reason why this is insecure? I only ask because the app I'm working on relies on elevated levels of security anyway. So just wondering if I really need to take these steps. What extra security are we getting? Vulnerabilities we are avoiding?

Electron relies on two processes: main and renderer.

The main process is the node (you can imagine it as the server) process, while the renderer process is the chromium process.

The communication between the main and the renderer usually happens through the ipc channel and one of the main concerns was that the renderer process could easily communicate with the main through ipcRenderer without any sort of "control", which is the reason why ipcRenderer is not exposed to the renderer process anymore.

In fact, as you can see, in this repo there is the preload.ts which is already warning you about this:

* Using the ipcRenderer directly in the browser through the contextBridge ist not really secure.

The "secure" way to implement this is to expose an API to the renderer from the preload where only what is expected to be received from the main process is effectively send. Further validation is of course required from the main process but still, in this way you cannot directly use ipcRenderer (and eventually other main libraries) in the renderer process.

from vite-reactts-electron-starter.

maxstue avatar maxstue commented on June 12, 2024 1

Thanks for explaning and helping out :)

from vite-reactts-electron-starter.

briosheje avatar briosheje commented on June 12, 2024

I had a similar problem, the solution in electron in general is to never use ipc in the client app at all, but you would rather make a bridge.

To make a brief history, the core idea in general is to exclude IPC entirely for safety reasons. In my real-case app scenario I did this:

file main.ts: you need to reference preload.ts in the browserWindow object, like this (in my case I had webpack, I need to check how to do that with vite, but I don't think it's a complex task, you can see an example in this repository):

const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
    },
    autoHideMenuBar: true
  });

preload.ts:

import { IPC_CHANNELS } from "./ipc";

import {
  contextBridge,
  ipcRenderer
} from "electron";

console.log('-loading preload.js-');

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
process.once('loaded', () => {
  contextBridge.exposeInMainWorld(
    "api", {
        send: (channel: IPC_CHANNELS, data: any) => {
            console.log(`[preload.ts] -> sending command ${channel}, data=${data}`)
            // whitelist channels
            let validChannels = Object.values(IPC_CHANNELS);
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel: IPC_CHANNELS, func: any) => {
            let validChannels = Object.values(IPC_CHANNELS);
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender` 
                ipcRenderer.on(channel, (event, ...args) => {
                  console.log(`[preload.ts] <- sending result for ${channel}, args=${args}`)
                  func(...args)
                });
            }
        }
    }
  );  
});

file ipc/index.ts

export enum IPC_CHANNELS {
  PING = 'PING'
}

Example in the client environment (renderer with react in this case):

useEffect(() => {
    window.api.receive(channel, (args) => {
      console.log('[useIpcChannel]:: setting message to', args);
      setMessage(args)
    });
  }, [channel]);

Note that window.api is what is exposed in preload.

The same as above can be applied with window.api.send

Example to handle a command from the server:

  ipcMain.on(
    IPC_CHANNELS.PING, (evt, args) => {
      console.log('-> got request:', args);
      win.webContents.send(IPC_CHANNELS.PING, args);
    }
  );

The core idea behind this is to have a shared file that has the IPC CHANNELS defined (through an enum in my case): in this way you can safely normalize the communication protocol between the main and the renderer process.

Hope this helps you to get an idea of how you can structure that.

from vite-reactts-electron-starter.

Seanmclem avatar Seanmclem commented on June 12, 2024

Thanks @briosheje i might try that. If you know, can you elaborate on the reason why this is insecure? I only ask because the app I'm working on relies on elevated levels of security anyway. So just wondering if I really need to take these steps. What extra security are we getting? Vulnerabilities we are avoiding?

from vite-reactts-electron-starter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.