Plugin WordPress sicuri: separare input, permessi e output
I plugin WordPress sicuri separano quattro responsabilità: ricevere i dati, verificare chi può agire, eseguire l’operazione e preparare l’output. Quando queste fasi vengono confuse in un’unica funzione, diventa più facile saltare un controllo, riutilizzare un dato nel contesto sbagliato o mostrare contenuto non correttamente codificato.
La sicurezza non si aggiunge alla fine con una singola funzione. È una proprietà dell’architettura e deve essere leggibile nel codice, nei test e nei log. Il principio di base della documentazione WordPress è semplice: non fidarsi dei dati, validarli o sanificarli prima dell’uso ed eseguire l’escaping al momento dell’output.
Plugin WordPress sicuri: il percorso di una richiesta
Ogni form, endpoint REST, chiamata AJAX, shortcode o comando amministrativo dovrebbe seguire una sequenza esplicita:
- Raccogliere: individuare origine, formato previsto e campi obbligatori.
- Autenticare e autorizzare: verificare sessione, nonce quando applicabile e capability richiesta.
- Validare: rifiutare valori che non rispettano tipo, intervallo o regola di business.
- Sanificare: pulire i dati quando non è possibile applicare una validazione chiusa.
- Elaborare e memorizzare: usare le API WordPress o query preparate.
- Eseguire l’escaping: adattare il dato al contesto HTML, attributo, URL o JavaScript nel momento in cui viene mostrato.
Questa separazione rende la revisione più efficace: ogni controllo ha un punto preciso e un errore non resta nascosto dentro una funzione troppo estesa.
Nonce e capability rispondono a domande diverse
Un nonce aiuta a verificare l’intenzione della richiesta e riduce il rischio di azioni indotte da un sito esterno. Non sostituisce l’autorizzazione. La capability stabilisce invece se l’utente ha il permesso di eseguire quell’azione. Un endpoint amministrativo dovrebbe quindi controllare entrambi quando il flusso lo richiede.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Operazione non autorizzata.' );
}
check_admin_referer( 'salva_impostazioni' );
La regola operativa è il privilegio minimo: richiedere la capability più specifica disponibile e ripetere il controllo su ogni richiesta sensibile, non soltanto quando viene costruita l’interfaccia.
Validazione e sanitizzazione non sono sinonimi
Se un campo ammette soltanto tre stati, la scelta più forte è confrontarlo con una lista consentita. Se il valore deve essere un identificatore, va convertito e verificato come tale. La sanitizzazione è utile per campi più aperti, ma non dimostra che il contenuto abbia senso per la regola di business.
WordPress offre funzioni come sanitize_text_field(), sanitize_email(), absint() e wp_kses_post(). La funzione va scelta in base al dato atteso, non applicata in modo generico a tutto l’array ricevuto.
Escaping tardivo e dipendente dal contesto
Lo stesso valore richiede funzioni diverse a seconda del punto in cui viene stampato. esc_html() è adatto al testo dentro un elemento, esc_attr() a un attributo ed esc_url() a un collegamento. Eseguire l’escaping il più tardi possibile permette di conoscere il contesto reale e riduce il rischio che il dato venga trasformato nuovamente prima della visualizzazione.
Per le query personalizzate conviene preferire le API WordPress. Quando serve SQL diretto, i valori devono passare da $wpdb->prepare(): concatenare input dentro una query rende il confine di sicurezza difficile da controllare.
Logging utile senza raccogliere dati sensibili
I log devono aiutare a capire che cosa è successo: operazione, esito, componente, utente o ruolo quando necessario, identificatore della richiesta e codice errore. Password, token, nonce, chiavi API e contenuti personali non devono finire nei messaggi. OWASP raccomanda formati coerenti e particolare attenzione a errori di validazione e autorizzazione.
Checklist prima del rilascio
- Ogni endpoint verifica capability e intenzione della richiesta?
- Ogni campo ha tipo, limiti e valori ammessi documentati?
- Le query usano API WordPress o placeholder preparati?
- L’escaping corrisponde al contesto di output?
- I messaggi di errore non espongono dettagli interni?
- I log escludono segreti e dati non necessari?
- Backup, staging e rollback seguono una procedura come quella descritta per WordPress 6.7.2?
Fonti ufficiali
- WordPress Developer Resources — Security
- WordPress — Sanitizing Data
- WordPress — Escaping Data
- OWASP — Authorization Cheat Sheet
Il tuo plugin rende visibile il confine tra input, autorizzazione, logica e output?
Possiamo rivedere architettura, endpoint e processo di rilascio del progetto.