Modello di sicurezza

Dare a un assistente AI l’accesso a un sito in produzione ha senso solo se ogni richiesta è autenticata, limitata a ciò che hai permesso, rallentata quando esagera, reversibile dove possibile e annotata. Ecco come lo fa il plugin 1.7.0, e dove sono i suoi limiti.

In questa pagina

Ogni richiesta, in ordine

  1. HTTPS: le richieste in HTTP semplice vengono rifiutate con 426.
  2. Token: si controllano firma, scadenza, emittente e revoca.
  3. Lista di IP consentiti, se il gestore ne ha salvata una.
  4. Scope: il token deve avere lo scope che serve alla route.
  5. Capability: l’utente WordPress dietro al token deve avere la capability richiesta dalla route. Ogni route con token ne controlla una.
  6. Limite di frequenza: per token e per amministratore collegato, più stretto sugli scope delicati.
  7. Conferma: le operazioni distruttive si fermano e chiedono una seconda chiamata esplicita.
  8. Protezioni: SQL, percorsi dei file e download remoti vengono controllati prima di eseguire qualsiasi cosa.
  9. Registro: la richiesta e il suo esito finiscono nel registro delle chiamate.

Token e chiave di firma

  • I token sono JSON Web Token firmati con HS256. La chiave è WPCB_JWT_SECRET, definita in wp-config.php e mai salvata nel database; deve avere almeno 32 caratteri, e il plugin ne suggerisce 64.
  • Un token contiene il suo emittente (l’indirizzo del sito), il momento di emissione, la scadenza, un ID unico, l’ID dell’utente WordPress a cui appartiene e i suoi scope. A ogni richiesta si controllano firma e scadenza, che l’emittente sia questo sito e che l’ID non sia revocato.
  • I token scadono dopo un periodo da 1 a 365 giorni (30 di default). Ruota chiave in Xaflo → Impostazioni invalida tutti i token in un colpo solo.
  • Dopo l’aggiornamento alla 1.7.0 la rotazione è obbligatoria: le versioni precedenti permettevano a un token amministratore in sola lettura di leggere wp-config.php. Vedi Aggiornare alla 1.7.0.
  • Il token viene mostrato una volta, quando lo crei. Dai a ogni client o persona un token suo, così puoi revocarne uno senza toccare gli altri.

Scope, capability e cosa equivale a un amministratore

Gli scope dicono cosa può chiedere un token; le capability di WordPress dicono cosa può fare il suo utente. Ogni route controlla entrambi, quindi un token non può mai superare il suo proprietario: un token creato da un Editor non può installare plugin anche se ha plugin:install. Le route di file, manutenzione, backup, registro, database e WP-CLI richiedono un amministratore.

Alcuni scope danno a chi ha il token il potere di un amministratore, qualunque cosa facciano le protezioni qui sotto: fs:admin, db:write, cli:exec, system:backup, plugin:write, theme:write e admin:login. Tratta un token che ne ha uno come la password di un amministratore, e tienilo fuori dall’uso quotidiano. Tutti gli scope sono in Permessi dei token.

Solo HTTPS

Il plugin rifiuta le richieste in HTTP semplice con 426 wpcb_upgrade_required, così i token non viaggiano mai in chiaro. Fanno eccezione gli host di sviluppo locale: localhost, 127.0.0.1, ::1 e i nomi che finiscono in .localhost, .test o .local, giudicati dall’indirizzo del sito stesso.

Limiti di frequenza

Ogni token può fare 60 richieste al minuto di default, contate con una finestra scorrevole; gli amministratori collegati a wp-admin sono contati allo stesso modo. Gli scope delicati hanno limiti propri, più bassi: 5 al minuto per cli:exec e system:backup, 10 per db:write e plugin:install, 20 per la scrittura di file di temi e plugin, 30 per la scrittura di media e la pubblicazione. Oltre il limite l’API risponde 429 con Retry-After.

Conferma in due passaggi

Le operazioni che distruggono dati, o che potrebbero chiuderti fuori, non vengono eseguite alla prima chiamata. Rispondono 428 con un riepilogo di cosa succederebbe e un token di conferma monouso; solo una seconda chiamata con quel token esegue l’operazione. Il token scade dopo cinque minuti ed è legato all’operazione, all’utente e, per le scritture, al contenuto esatto.

Operazioni che chiedono conferma:

  • scritture SQL (INSERT, UPDATE, DELETE);
  • il ripristino di un backup;
  • l’eliminazione definitiva di un articolo o di una pagina, e l’eliminazione di media;
  • l’installazione di un plugin da uno zip o dalla directory di WordPress.org, e la sostituzione di un plugin installato con uno zip caricato;
  • il cambio di tema;
  • il cambio dell’indirizzo del sito (siteurl, home) o dell’email dell’amministratore;
  • con fs:admin: ogni sovrascrittura, rinomina ed eliminazione, e ogni scrittura di file eseguibili o di configurazione del server.

Le conferme proteggono dagli incidenti, non da chi possiede il token. Chi ha il token può chiedere una conferma e usarla con due chiamate automatiche. La differenza la fa chi risponde: Xaflo Desktop 2.0 e il server MCP 1.3 ti mostrano sempre la modifica e aspettano il tuo sì; non confermano mai da soli.

Backup e annullamento

Un backup completo viene fatto solo quando lo chiedi; le altre protezioni sono più piccole e automatiche:

  • Le modifiche ad articoli e pagine salvano una revisione di WordPress prima di cambiare qualcosa.
  • Sovrascrivere un file con le route dei file conserva la versione precedente nella cartella dei backup del plugin e restituisce l’id del backup; anche la scrittura di file di temi e plugin conserva la versione precedente.
  • wp_backup_create fa un backup completo (database, file o entrambi) in un unico zip in wp-content/wpcb-backups/; wp_backup_restore lo riporta indietro, con conferma. Il ripristino avviene in una transazione, non riporta mai la cartella del bridge, i suoi token o le sue impostazioni, e rimette utenti e ruoli com’erano nel backup.
  • Su Apache il plugin blocca l’accesso web alla cartella dei backup. Su nginx aggiungi tu una regola:
nginx
location ~ /wpcb-backups/ { deny all; }

File, SQL e download

File

  • La lettura richiede site:read e un amministratore. I segreti vengono rifiutati e nascosti da elenchi e ricerca: tutto ciò che si chiama come wp-config, i file .env, i file *.bak*, i dump SQL, debug.log, .user.ini, php.ini, web.config, .htpasswd, e tutto ciò che sta sotto wpcb-backups/, .git/ o .svn/, controllando il percorso richiesto e quello risolto.
  • La scrittura con site:write funziona solo dentro la cartella uploads, e solo su tipi inerti (documenti, immagini, audio, video, archivi). Non passa mai da un collegamento simbolico, e : è rifiutato in qualsiasi percorso.
  • La scrittura con fs:admin raggiunge qualsiasi file sotto la cartella del sito tranne i limiti fissi: i nomi protetti, la cartella del sito stessa, la cartella del bridge, la cartella dei backup e qualsiasi cartella che li contenga.

SQL

  • /db/query richiede un amministratore. Un’istruzione per chiamata, ogni tabella deve avere il prefisso del tuo sito, e si accettano solo SELECT, INSERT, UPDATE e DELETE; modifiche di struttura, altri database, WITH, commenti eseguibili, accesso ai file e funzioni di attesa vengono rifiutati. I risultati di una SELECT senza limite si fermano a 1000 righe.
  • Gli hash delle password vengono tolti da ogni risultato.
  • Le scritture richiedono InnoDB e avvengono in una transazione. Se sono cambiati utenti, ruoli, token del plugin o opzioni protette (indirizzo del sito, email dell’amministratore, plugin attivi, tema e altro), l’istruzione viene annullata.
  • La route viene rifiutata del tutto con modalità SQL o set di caratteri della connessione in cui i suoi controlli non sarebbero affidabili.

WP-CLI

Spento su ogni sito finché il proprietario non lo attiva. Quando è attivo, un comando deve coincidere esattamente con una voce della lista consentita, le opzioni sono ammesse per singolo comando, le opzioni che caricano codice vengono rifiutate, i metacaratteri della shell respinti, ogni argomento protetto, e ogni esecuzione si ferma dopo 30 secondi con al massimo 16 KB di output.

Download remoti

Quando il plugin scarica qualcosa per conto tuo (un’immagine da un URL, lo zip di un plugin, un controllo dei link), la richiesta passa da una protezione SSRF che controlla prima la destinazione, con verifica TLS.

Accesso rapido

Un token con admin:login, di un amministratore, può chiedere un link monouso che fa entrare quello stesso utente in wp-admin. Il segreto del link è di 256 bit casuali, salvato solo come hash, valido 60 secondi e utilizzabile una volta. Smette di funzionare quando il token viene revocato o scade, quando la chiave viene ruotata, quando l’utente perde i diritti di amministratore, e quando l’indirizzo del browser non supera la lista di IP consentiti. Viene rifiutato senza HTTPS e mentre è attivo un plugin noto di accesso a due fattori, perché il link salterebbe il secondo passaggio. Emissione e uso finiscono nel registro; il link stesso mai. Il server MCP non lo offre ai modelli, di proposito.

Registro delle chiamate

Ogni richiesta viene registrata una volta, rifiuti compresi, con ora, ID del token, utente, route, metodo, scope richiesto, esito e durata. Password e chiavi vengono oscurate; contenuto dei file, CSS, valori SQL e argomenti CLI vengono sostituiti dalla loro dimensione; gli URL vengono salvati senza credenziali né query string. Lo leggi in Xaflo → Registro di audit. Le voci restano 90 giorni di default (da 1 a 3650), e un processo giornaliero elimina quelle più vecchie e i token scaduti.

L’IP del client è quello vero: l’ultimo passaggio non fidato di X-Forwarded-For, considerato solo dai proxy indicati dal gestore; CF-Connecting-IP non è considerato affidabile.

Limiti dichiarati

Dalle note di rilascio della 1.7.0, perché tu possa decidere cosa concedere:

  • fs:admin può scrivere un file nuovo, con un nome ordinario, ovunque fuori dai limiti fissi senza conferma, quindi può inserire codice con una sola chiamata.
  • db:write può ancora cambiare la maggior parte delle tabelle; la protezione SQL è un filtro sulla richiesta, non un parser SQL completo.
  • cli:exec può leggere tutte le opzioni, e il ripristino di un backup rimette utenti e ruoli com’erano.
  • Le richieste alle route di installazione e all’anteprima della manutenzione non finiscono ancora nel registro.

Cosa invia il plugin

Nulla di sua iniziativa. Non contatta servizi Xaflo e non invia telemetria. La versione self-hosted controlla gli aggiornamenti su questo sito e installa un rilascio solo se il manifest ha uno SHA-256, il download è in https su xaflo.com e lo zip coincide con l’hash. Tutto il resto è una risposta a una richiesta fatta da te, o dal tuo assistente con il tuo token.

Segnalare un problema di sicurezza

Scrivi in privato a security@xaflo.com, per favore senza aprire segnalazioni pubbliche. Lo stesso contatto è in /.well-known/security.txt.