Best Practice di Sicurezza
La sicurezza è un aspetto critico nello sviluppo con Electron. Poiché le applicazioni Electron hanno accesso alle API di Node.js e al sistema operativo, una vulnerabilità nel renderer può avere conseguenze gravi. Seguire queste best practice è fondamentale.
Le 10 Regole d’Oro
1. Disabilitare nodeIntegration
Non abilitare mai l’accesso diretto a Node.js nel Renderer Process:
// ✅ SICURO (default)
new BrowserWindow({
webPreferences: {
nodeIntegration: false,
},
});
// ❌ PERICOLOSO - Mai fare questo!
new BrowserWindow({
webPreferences: {
nodeIntegration: true, // Un attaccante potrebbe eseguire codice sul sistema
},
});
2. Abilitare Context Isolation
Mantieni il preload script isolato dal contenuto web:
// ✅ SICURO (default da Electron 12+)
new BrowserWindow({
webPreferences: {
contextIsolation: true,
},
});
3. Usare il Preload e contextBridge
Esponi solo le API strettamente necessarie:
// ✅ SICURO - Esponi solo ciò che serve
contextBridge.exposeInMainWorld('api', {
readFile: (path) => ipcRenderer.invoke('fs:readFile', path),
saveFile: (path, data) => ipcRenderer.invoke('fs:saveFile', path, data),
});
// ❌ PERICOLOSO - Espone l'intero ipcRenderer
contextBridge.exposeInMainWorld('api', {
ipcRenderer: ipcRenderer,
});
4. Validare Tutti gli Input IPC
Nel Main Process, valida sempre i dati ricevuti dal renderer:
// main.js
ipcMain.handle('fs:readFile', async (_event, filePath) => {
// ✅ Valida il percorso
if (typeof filePath !== 'string') {
throw new Error('Percorso non valido');
}
// ✅ Previeni path traversal
const resolvedPath = path.resolve(filePath);
const allowedDir = path.resolve(app.getPath('userData'));
if (!resolvedPath.startsWith(allowedDir)) {
throw new Error('Accesso non autorizzato');
}
return fs.readFileSync(resolvedPath, 'utf-8');
});
5. Non Disabilitare webSecurity
La web security protegge da attacchi cross-origin:
// ✅ SICURO (default)
new BrowserWindow({
webPreferences: {
webSecurity: true,
},
});
// ❌ PERICOLOSO
new BrowserWindow({
webPreferences: {
webSecurity: false, // Disabilita la politica same-origin
},
});
6. Definire una Content Security Policy
<!-- index.html -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
7. Validare URL con openExternal
ipcMain.handle('shell:openExternal', async (_event, url) => {
try {
const parsed = new URL(url);
// ✅ Permetti solo protocolli sicuri
if (!['https:', 'http:', 'mailto:'].includes(parsed.protocol)) {
throw new Error('Protocollo non consentito');
}
await shell.openExternal(url);
} catch (error) {
console.error('URL non valido:', error.message);
}
});
8. Controllare la Navigazione
Impedisci la navigazione verso URL non previsti:
mainWindow.webContents.on('will-navigate', (event, url) => {
const parsedUrl = new URL(url);
// Permetti solo la navigazione locale
if (parsedUrl.protocol !== 'file:') {
event.preventDefault();
}
});
// Impedisci l'apertura di nuove finestre
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith('https://') || url.startsWith('http://')) {
shell.openExternal(url);
}
return { action: 'deny' };
});
9. Usare il Sandbox
Il sandbox limita le capacità del Renderer Process:
new BrowserWindow({
webPreferences: {
sandbox: true,
preload: path.join(__dirname, 'preload.js'),
},
});
10. Mantenere Electron Aggiornato
Le versioni più recenti di Electron includono patch di sicurezza per Chromium e Node.js. Aggiorna regolarmente:
npm update electron
Checklist di Sicurezza
| Controllo | Stato Consigliato |
|---|---|
nodeIntegration |
false |
contextIsolation |
true |
sandbox |
true |
webSecurity |
true |
| Content Security Policy | Configurata |
| Validazione input IPC | Implementata |
openExternal validato |
Implementato |
| Navigazione controllata | Implementata |
| Electron aggiornato | Ultima versione stabile |
Errori Comuni da Evitare
- Caricare contenuti remoti senza CSP — Permette attacchi XSS
- Esporre API troppo generiche — Un canale IPC generico dà troppo potere al renderer
- Fidarsi dei dati dal renderer — Il renderer è come un browser: i dati possono essere manipolati
- Non validare i percorsi — Path traversal può dare accesso a file sensibili
- Ignorare gli aggiornamenti — Vulnerabilità note in Chromium/Node.js restano aperte