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