
Nei giorni scorsi l’Agenzia per la Cybersicurezza Nazionale (ACN) ha pubblicato una segnalazione relativa ad alcune vulnerabilità individuate in n8n, la piattaforma open source per l’automazione dei workflow che utilizzo in un’installazione locale tramite Docker.
La segnalazione è piuttosto seria: riguarda diverse vulnerabilità, alcune classificate con severità High, che possono consentire, in determinate condizioni, esecuzione di codice, accesso a file locali, aggiramento di restrizioni e divulgazione di informazioni.
La prima domanda, naturalmente, è stata:
La mia installazione è vulnerabile?
Sommario
Controllare la versione di n8n
Nel mio caso n8n gira all’interno di un container Docker chiamato n8n. Possiamo quindi chiedere direttamente al programma quale versione stia eseguendo:
docker exec n8n n8n --version
Il risultato è stato:
2.34.6
Consultando i Security Advisories ufficiali del progetto n8n su GitHub, si scopre che per diverse delle vulnerabilità segnalate le correzioni sono disponibili, nel ramo 2.35, a partire dalla versione 2.35.4 (i problemi erano già stati notificati e corretti nel sito Github di n8n il 19 agosto, due giorni prima della segnalazione dell’Agenzia nazionale per la cybersicurezza).
La mia 2.34.6 era quindi precedente alle versioni corrette.
Prima regola: un piccolo backup
Prima di aggiornare è sempre opportuno mettere al sicuro ciò che ci interessa.
Nel mio caso avevo soltanto due workflow in lavorazione, per cui è stato sufficiente esportarli dall’interfaccia di n8n in formato JSON.
È importante osservare che questo non costituisce necessariamente un backup completo dell’installazione: n8n conserva separatamente workflow, configurazioni e credenziali. Nel nostro caso, però, l’esportazione dei workflow rappresentava una semplice precauzione aggiuntiva.
Ed è qui che Docker ci rende la vita particolarmente semplice.
Il container non è il dato
Una delle idee fondamentali nell’utilizzo di Docker è che dovremmo poter distruggere e ricreare un container senza perdere i dati persistenti.
Se l’installazione è stata configurata correttamente, i dati di n8n risiedono infatti in un volume o in una directory montata dall’host.
Possiamo quindi sostituire il container che esegue la vecchia versione di n8n mantenendo i nostri dati.
Ci spostiamo innanzitutto nella directory contenente il nostro file compose.yml (o docker-compose.yml) e arrestiamo lo stack:
docker compose down
Se eseguiamo questo comando da una directory qualsiasi potremmo ottenere:
no configuration file provided: not found
Non è un problema di Docker: semplicemente Compose non ha trovato nella directory corrente il file che descrive lo stack. Quindi è necessario spostarsi nella cartella in cui si trova il docker-compose.yml che ha generato il container prima di lanciare il compose.
Scaricare l’immagine aggiornata
A questo punto possiamo chiedere a Docker di recuperare l’immagine più recente:
docker compose pull
e ricreare i container:
docker compose up -d
Il parametro -d avvia i container in detached mode, lasciandoli in esecuzione in background.
Possiamo verificare che tutto sia ripartito:
docker ps
e soprattutto controllare nuovamente la versione:
docker exec n8n n8n --version
Questa volta il risultato è stato:
2.35.7
Siamo quindi passati da:
2.34.6 → 2.35.7
La nuova versione è successiva alla 2.35.4, che contiene le correzioni richieste dagli advisory considerati.
Ma i workflow?
Aprendo nuovamente l’interfaccia web di n8n, i workflow erano regolarmente al loro posto.
Ho quindi eseguito il workflow che utilizzo come test: anche le credenziali e i collegamenti con gli altri servizi erano rimasti correttamente configurati e l’esecuzione è terminata senza errori.
L’aggiornamento era concluso.
Una piccola procedura da ricordare
Per una installazione Docker di questo tipo la procedura di aggiornamento si riduce sostanzialmente a:
docker compose pull docker compose down docker compose up -d docker exec n8n n8n --version
seguita, naturalmente, da un test dei workflow più importanti.
Nel mio compose.yml utilizzo attualmente il tag latest. Questo rende molto comodo recuperare le nuove versioni semplicemente eseguendo docker compose pull.
È una comodità che ha però un prezzo: latest significa l’ultima immagine pubblicata, non necessariamente l’ultima patch compatibile con quella che sto usando. In un ambiente di produzione può quindi essere preferibile indicare esplicitamente una versione dell’immagine e pianificare gli aggiornamenti.
Per una piccola installazione personale e controllata, invece, mantenere latest può essere una scelta pragmatica, purché prima di aggiornare si disponga di un backup e si verifichi poi il funzionamento dei workflow.
Una considerazione finale
Questo piccolo incidente è anche un buon esempio del motivo per cui container e persistenza dei dati devono essere pensati come due cose distinte.
Abbiamo eliminato il container che eseguiva n8n 2.34.6, scaricato una nuova immagine e creato un nuovo container con n8n 2.35.7.
Eppure, riaprendo l’applicazione, abbiamo ritrovato i nostri workflow.
Il container era sacrificabile.
I dati no.
Ed è esattamente così che dovrebbe essere.
Riferimenti
- With a little help from my friend ChatGPT
- Agenzia Nazionale per la Cybersicurezza
- n8n Github Advisories
Commenti recenti