Come Sanificare ed Escapare i Dati in un Tema WordPress: Guida Pratica

By Alberta Trentino

La sicurezza di un tema WordPress passa quasi sempre da due concetti fondamentali: sanitize ed escape. Ignorare queste pratiche significa esporre il proprio sito a vulnerabilità XSS, injection e manipolazione dei dati. In questa guida pratica vediamo quando e come utilizzare le funzioni native di WordPress per proteggere il proprio tema, con esempi di codice reali che puoi copiare e adattare ai tuoi progetti. wpvip.com propone un buon riepilogo sul tema.

La regola d’oro: Sanitize Early, Escape Late

Prima di entrare nel codice, memorizza questo principio che guida ogni sviluppatore WordPress:

  • Sanitize early: pulisci i dati in ingresso appena entrano nel sistema (form, opzioni, meta box).
  • Escape late: fai l’escape dei dati in uscita nell’ultimo momento possibile, cioè quando li stampi in HTML.
  • Validate: verifica che il dato corrisponda al formato atteso (email, numero, URL) prima di salvarlo.

Sanitizzare e fare escape sono operazioni complementari, non intercambiabili. Un dato sanificato in input può ancora essere pericoloso in output se non viene escapato correttamente in base al contesto.

wordpress code security

Le funzioni di Sanitize in WordPress

Le funzioni di sanificazione si occupano di ripulire i dati provenienti dall’utente prima di salvarli nel database o utilizzarli internamente.

sanitize_text_field()

Rimuove tag HTML, righe multiple, tab e caratteri invisibili. Perfetta per input di testo semplice come nomi, titoli o campi di ricerca.

// Salvataggio di un campo testo da un form
$nome = isset( $_POST['nome_utente'] ) ? sanitize_text_field( wp_unslash( $_POST['nome_utente'] ) ) : '';
update_post_meta( $post_id, '_nome_utente', $nome );

wp_kses() e wp_kses_post()

Quando devi permettere alcuni tag HTML (ad esempio in una biografia o in una descrizione), usa wp_kses() per definire i tag ammessi o wp_kses_post() per applicare le regole standard dei post WordPress.

$tag_permessi = array(
    'a'      => array( 'href' => array(), 'title' => array() ),
    'strong' => array(),
    'em'     => array(),
    'br'     => array(),
);

$biografia = wp_kses( $_POST['biografia'], $tag_permessi );
update_user_meta( $user_id, 'biografia_estesa', $biografia );

Altre funzioni di sanitize utili

Funzione Uso consigliato
sanitize_email() Indirizzi email
sanitize_title() Slug e URL friendly
sanitize_key() Chiavi interne (lowercase, alfanumerici)
sanitize_textarea_field() Testo multilinea senza HTML
sanitize_hex_color() Colori esadecimali (Customizer)
absint() Numeri interi positivi (ID)

Le funzioni di Escape in WordPress

L’escape converte i caratteri speciali in entità HTML sicure, evitando che dati potenzialmente malevoli vengano interpretati come codice dal browser.

esc_html()

Da usare quando stampi del testo all’interno di un elemento HTML.

<h2><?php echo esc_html( get_the_title() ); ?></h2>
<p><?php echo esc_html( get_post_meta( get_the_ID(), '_nome_utente', true ) ); ?></p>

esc_url()

Indispensabile per qualunque URL, sia negli attributi href che src.

<a href="<?php echo esc_url( get_permalink() ); ?>">
    <?php echo esc_html( get_the_title() ); ?>
</a>

<img src="<?php echo esc_url( get_theme_mod( 'logo_url' ) ); ?>" alt="Logo">

esc_attr()

Per tutto ciò che finisce dentro un attributo HTML (title, alt, data-*, class dinamiche).

<input type="text" 
       name="cerca" 
       value="<?php echo esc_attr( get_search_query() ); ?>" 
       placeholder="<?php esc_attr_e( 'Cerca...', 'mumble-theme' ); ?>">

esc_textarea() ed esc_js()

  • esc_textarea(): per il contenuto di una textarea.
  • esc_js(): per stringhe inline dentro JavaScript (usa comunque wp_localize_script quando possibile).

wp_kses_post() in output

Se devi stampare del contenuto HTML formattato (proveniente ad esempio da un campo del Customizer che permette tag), usa wp_kses_post() anche in fase di output.

<div class="footer-credits">
    <?php echo wp_kses_post( get_theme_mod( 'footer_credits' ) ); ?>
</div>
wordpress code security

Casi d’uso concreti nello sviluppo di temi

1. Customizer: sanitize_callback obbligatorio

Ogni setting del Customizer deve avere un sanitize_callback. Senza di esso WordPress segnala un errore e i dati non vengono validati. Un approccio simile si ritrova su unboundzine.com.

$wp_customize->add_setting( 'colore_primario', array(
    'default'           => '#0073aa',
    'sanitize_callback' => 'sanitize_hex_color',
    'transport'         => 'refresh',
) );

$wp_customize->add_setting( 'testo_header', array(
    'default'           => '',
    'sanitize_callback' => 'sanitize_text_field',
) );

2. Loop personalizzato con dati sicuri

if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        $sottotitolo = get_post_meta( get_the_ID(), '_sottotitolo', true );
        $link_esterno = get_post_meta( get_the_ID(), '_link_esterno', true );
        ?>
        <article id="post-<?php echo esc_attr( get_the_ID() ); ?>">
            <h2><?php echo esc_html( get_the_title() ); ?></h2>
            <p class="subtitle"><?php echo esc_html( $sottotitolo ); ?></p>
            <a href="<?php echo esc_url( $link_esterno ); ?>" rel="noopener">
                <?php esc_html_e( 'Vai al sito', 'mumble-theme' ); ?>
            </a>
        </article>
        <?php
    endwhile;
endif;

3. Form di ricerca con nonce

if ( isset( $_POST['mumble_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['mumble_nonce'] ), 'mumble_action' ) ) {
    $query = isset( $_POST['q'] ) ? sanitize_text_field( wp_unslash( $_POST['q'] ) ) : '';
    // Elabora la query in sicurezza...
}

Tabella riassuntiva: quale funzione usare?

Contesto Funzione Sanitize (input) Funzione Escape (output)
Testo semplice sanitize_text_field() esc_html()
URL esc_url_raw() esc_url()
Attributo HTML sanitize_text_field() esc_attr()
HTML consentito wp_kses() / wp_kses_post() wp_kses_post()
Email sanitize_email() esc_html() / antispambot()
ID numerico absint() esc_attr() / intval()
Textarea sanitize_textarea_field() esc_textarea()
wordpress code security

Errori comuni da evitare

  1. Usare solo sanitize senza escape: il dato può essere pulito in input ma diventare pericoloso in un contesto diverso in output.
  2. Escape con la funzione sbagliata: usare esc_html() dentro un attributo href non protegge da javascript: URI.
  3. Dimenticare wp_unslash(): WordPress aggiunge slash automaticamente ai dati POST, va rimossi prima di sanificare.
  4. Sanificare due volte: applicare wp_kses() e poi sanitize_text_field() distrugge i tag che volevi permettere.
  5. Non usare nonce: sanitize ed escape non proteggono dalle richieste CSRF, servono i nonce.

FAQ

Devo fare escape anche dei dati che ho già sanificato in input?

Sì, sempre. Sanitize ed escape hanno scopi diversi: il primo pulisce ciò che salvi, il secondo protegge il contesto di output. Un dato sanificato può comunque contenere caratteri interpretabili in HTML, JS o URL.

Qual è la differenza tra esc_url() ed esc_url_raw()?

esc_url() è pensata per l’output in HTML e converte le entità, mentre esc_url_raw() è pensata per il salvataggio in database o per uso interno, senza conversione delle entità. Vedi wpscholar.com per il loro punto di vista.

Posso usare wp_kses_post() al posto di sanitize_text_field()?

No. wp_kses_post() permette molti tag HTML, mentre sanitize_text_field() li rimuove tutti. Scegli in base al tipo di dato che ti aspetti.

I temi vengono rifiutati dalla directory WordPress.org se non uso queste funzioni?

Sì. Il Theme Review Team richiede l’uso corretto di sanitize ed escape per tutti i dati dinamici. Un tema che non segue queste regole non passa la review.

Come posso testare se il mio tema è sicuro?

Puoi usare il plugin Theme Check e strumenti come PHP_CodeSniffer con gli standard WordPress Coding Standards, che segnalano automaticamente output non escapati e input non sanificati.

Conclusione

Padroneggiare le funzioni di sanitize ed escape in un tema WordPress non è opzionale: è la base della sicurezza. Ricorda sempre la regola sanitize early, escape late, scegli la funzione giusta per il contesto e non dare mai per scontato che un dato sia sicuro solo perché viene dal database. Se stai sviluppando un tema personalizzato per il tuo progetto, in Mumble Studio possiamo aiutarti a costruire un codice pulito, sicuro e conforme agli standard WordPress.

Leave a Comment