00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Sandboxing

Il sandboxing in Electron limita le capacità del Renderer Process, restringendo l’accesso alle risorse del sistema. Quando il sandbox è attivo, il renderer opera in un ambiente isolato simile a un normale tab del browser.

Cos’è il Sandbox

Il sandbox di Chromium limita ciò che il Renderer Process può fare:

  • Senza sandbox: Il renderer può (potenzialmente) accedere al file system, alla rete e ad altre risorse del sistema
  • Con sandbox: Il renderer è isolato e può comunicare con il sistema solo attraverso canali IPC controllati
const win = new BrowserWindow({
  webPreferences: {
    sandbox: true,
    preload: path.join(__dirname, 'preload.js'),
  },
});

Effetti del Sandbox

Quando il sandbox è attivo, nel preload script:

Funzionalità Senza Sandbox Con Sandbox
require('electron') ✅ Completo ✅ Solo contextBridge, ipcRenderer, webFrame
require('node:fs') ❌ Non disponibile
require('node:path') ❌ Non disponibile
process.env ✅ Parziale (solo variabili sicure)
process.versions
Moduli nativi ❌ Non disponibili

Preload Script con Sandbox

Con il sandbox attivo, il preload script ha accesso limitato. Usa solo le API di Electron disponibili:

// preload.js - Con sandbox: true
const { contextBridge, ipcRenderer } = require('electron');

// ✅ Funziona - contextBridge e ipcRenderer sono disponibili
contextBridge.exposeInMainWorld('electronAPI', {
  readFile: (path) => ipcRenderer.invoke('fs:readFile', path),
  writeFile: (path, data) => ipcRenderer.invoke('fs:writeFile', path, data),
  getVersion: () => ipcRenderer.invoke('app:getVersion'),
});

// ❌ NON funziona con sandbox
// const fs = require('node:fs');       // Errore
// const path = require('node:path');   // Errore

Tutta la logica che richiede Node.js deve essere nel Main Process:

// main.js - Tutte le operazioni Node.js qui
const fs = require('node:fs/promises');
const path = require('node:path');

ipcMain.handle('fs:readFile', async (_event, filePath) => {
  return await fs.readFile(filePath, 'utf-8');
});

ipcMain.handle('fs:writeFile', async (_event, filePath, data) => {
  await fs.writeFile(filePath, data, 'utf-8');
});

ipcMain.handle('app:getVersion', () => {
  return app.getVersion();
});

Sandbox Globale

Puoi abilitare il sandbox per tutti i renderer dell’applicazione:

app.enableSandbox(); // Abilita per tutti i renderer

app.whenReady().then(() => {
  // Tutte le finestre create avranno sandbox: true
  const win = new BrowserWindow({
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });
});

Quando Usare il Sandbox

Consigliato (sandbox: true)

  • App che caricano contenuti da internet
  • App che gestiscono dati sensibili
  • App distribuite a un ampio pubblico
  • Qualsiasi nuova applicazione

Può essere omesso

  • App interne/aziendali con codice completamente controllato
  • Strumenti di sviluppo dove serve accesso diretto a Node.js nel preload
  • Prototipi rapidi (ma attivalo prima della distribuzione)

Migrare al Sandbox

Se hai un’app esistente senza sandbox, ecco i passi:

1. Sposta la logica Node.js dal preload al main

// PRIMA (senza sandbox)
// preload.js
const fs = require('node:fs');
contextBridge.exposeInMainWorld('api', {
  readFile: (path) => fs.readFileSync(path, 'utf-8'),
});

// DOPO (con sandbox)
// preload.js
contextBridge.exposeInMainWorld('api', {
  readFile: (path) => ipcRenderer.invoke('fs:readFile', path),
});

// main.js (nuovo handler)
ipcMain.handle('fs:readFile', async (_event, filePath) => {
  return await fs.readFile(filePath, 'utf-8');
});

2. Abilita il sandbox

new BrowserWindow({
  webPreferences: {
    sandbox: true,
    preload: path.join(__dirname, 'preload.js'),
  },
});

3. Testa l’applicazione

Verifica che tutte le funzionalità continuino a funzionare con il sandbox attivo.

Best Practice

  1. Abilita il sandbox per le nuove app — è più facile iniziare con il sandbox che aggiungerlo dopo
  2. Centralizza la logica Node.js nel Main Process — il preload è solo un ponte IPC
  3. Valida i dati nel Main Process — il renderer (anche sandbox) potrebbe inviare dati manipolati
  4. Usa app.enableSandbox() per applicare il sandbox a tutti i renderer
  5. Testa regolarmente — assicurati che il sandbox non rompa funzionalità dopo gli aggiornamenti