il blog delle automazioni

Debug API WordPress: tre ore per una password incollata dal sito sbagliato

Sommario

La risposta breve

Quando WordPress rifiuta l’autenticazione REST, la colpa non è quasi mai del firewall o dell’hosting. Prima di toccare qualsiasi configurazione, scrivi una route di cinque righe che stampa se l’header Authorization arriva a PHP. Se arriva, il problema è nella credenziale. Se non arriva, allora si parla di server.

Questo articolo ricostruisce il debug API WordPress di un’integrazione rotta, mostra i sospettati plausibili che si sono rivelati innocenti, e spiega perché un probe deterministico vale più di dieci ipotesi in fila. Se stai costruendo una macchina di automazione sopra WordPress, le guardie che descrivo qui ti risparmiano ore.

Il contesto: un’integrazione che smette di autenticarsi

Lo scenario è classico. Hai un WordPress che espone la REST API. Un sistema esterno — Make, n8n, un webhook custom — chiama un endpoint con Basic Auth usando una Application Password. Funzionava. Poi smette.

Le risposte che ricevi non aiutano. WordPress restituisce 401 Unauthorized oppure, peggio, un 403 che non distingue tra «credenziale sbagliata» e «firewall che ha bloccato la richiesta». I log dell’hosting sono silenziosi. Nessun errore esplicito. Il sistema ha smesso di funzionare con la stessa sicurezza con cui funzionava prima.

Un’automazione senza guardie esegue sbagliato con la stessa sicurezza con cui esegue giusto.

Questo è esattamente il tipo di rottura silenziosa che costa di più: nessun alert, nessuna notifica, solo dati che non arrivano e nessuno che se ne accorge subito.

Schema a mano su carta con i possibili sospettati nel debug API WordPress: hosting, firewall, credenziali

I sospettati plausibili nel debug API WordPress

L’hosting che spoglia l’header Authorization

Non è raro. Alcuni hosting condivisi, in particolare quelli su Apache con PHP in modalità CGI o FastCGI, eliminano l’header Authorization prima che arrivi a PHP. La richiesta raggiunge il server, riceve un 200 dall’infrastruttura, ma PHP non vede mai le credenziali. WordPress non può autenticare nessuno perché non sa che stai cercando di autenticarti.

Il fix classico è aggiungere questa riga al .htaccess:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

O in alternativa, per Nginx, passare l’header esplicitamente nel blocco fastcgi_param. La documentazione ufficiale della REST API di WordPress lo menziona come problema noto.

Il firewall e l’anti-enumerazione

Wordfence, Cloudflare, i WAF di molti hosting: tutti possono bloccare richieste sulla base dello user-agent, dell’IP, del numero di tentativi ravvicinati. Il problema specifico è che questi strumenti spesso restituiscono risposte identiche a quelle di un’autenticazione fallita legittima. Un 403 da Wordfence e un 403 da WordPress per credenziale errata si distinguono solo guardando il corpo della risposta con attenzione, e non sempre.

L’anti-enumerazione utenti aggiunge un altro strato di ambiguità: WordPress, quando è configurato per nascondere se un utente esiste, risponde nello stesso modo sia che l’utente non esista sia che la password sia sbagliata. Fare debug con curl in quel contesto porta spesso a conclusioni false.

Le Application Password disabilitate

Le Application Password sono attive di default su WordPress dalla versione 5.6, ma richiedono HTTPS. Su un sito senza certificato SSL valido, o su un ambiente di sviluppo locale non configurato correttamente, vengono disabilitate automaticamente. Possono anche essere disabilitate da un plugin di sicurezza, o da un filtro custom nel tema. Un 401 che dice «application passwords are not available» è esplicito; un 401 generico non lo è.

Il problema con i test ambigui

Ogni sospettato qui sopra è plausibile. È anche possibile che siano più di uno a interagire. Il guaio è che i test esterni — chiamate dirette da curl, test da Postman, controlli dal pannello dell’hosting — sono tutti ambigui in questo contesto.

Se il firewall blocca lo user-agent di curl, la tua chiamata di test fallisce per una ragione diversa da quella che stai cercando di isolare. Se l’anti-enumerazione è attiva, non riesci a capire se il problema è l’utente o la password. Se stai testando da un IP diverso da quello del sistema che fa le chiamate reali, le regole del WAF potrebbero non applicarsi nello stesso modo.

Dieci ipotesi plausibili non convergono. Ogni nuova ipotesi aggiunge superficie, non riduce il problema. Quello che serve è un probe che risponde a una sola domanda in modo determinato.

Diagramma a lavagna con due rami di un probe deterministico per il debug di autenticazione REST

La svolta: una sonda da cinque righe

La sonda è una route REST custom che non fa niente di utile, tranne una cosa: stampare se l’header Authorization è arrivato a PHP e, se sì, con quale valore.

add_action( 'rest_api_init', function () {
    register_rest_route( 'debug/v1', '/auth-check', [
        'methods'             => 'GET',
        'callback'            => function ( $request ) {
            $auth = $request->get_header( 'authorization' );
            return rest_ensure_response( [
                'authorization_received' => ! empty( $auth ),
                'authorization_value'    => $auth ?? 'nessuno',
            ] );
        },
        'permission_callback' => '__return_true',
    ] );
} );

Chiami GET /wp-json/debug/v1/auth-check passando le credenziali che usi nel sistema di automazione. Tre casi possibili:

Caso 1 — authorization_received: false. L’header non arriva a PHP. Il problema è l’hosting o il server web: Apache spoglia il header, Nginx non lo passa. Vai al .htaccess o alla configurazione FastCGI.

Caso 2 — authorization_received: true ma il valore è strano o troncato. Il WAF o un proxy stanno modificando l’header. Caso raro, ma succede con certi CDN.

Caso 3 — authorization_received: true e il valore sembra corretto. L’header arriva intatto. Il problema è nella credenziale stessa.

Nel caso che ha originato questo articolo: caso 3. L’header arrivava benissimo. La password incollata nel sistema di automazione era quella di un altro sito WordPress — stesso dominio di staging, credenziali diverse, generata mesi prima durante un test. Nessuna configurazione rotta, nessun firewall attivo, nessun bug di autenticazione. Una stringa sbagliata in un campo.

Tre ore di analisi. Cinque minuti con la sonda.

Come costruire questa guardia in un sistema di automazione

Se stai automatizzando un’agenzia con WordPress come backend — per i contenuti, per la gestione dei lead, per qualsiasi endpoint custom — la sonda non va usata solo in emergenza. Va integrata come check permanente nel flusso.

Il modo pratico: nel tuo scenario Make o nel tuo workflow n8n, il primo modulo chiama /debug/v1/auth-check prima di fare qualsiasi operazione reale. Se la risposta non è quella attesa, il flusso si ferma e manda un alert. Non continua silenziosamente a fallire su ogni endpoint successivo.

Questo è il concetto di guardia applicato al debug API WordPress: non aspetti che l’errore emerga a valle, su un endpoint di scrittura, dopo aver creato dati parziali o non creato nulla. Lo intercetti all’ingresso.

Alcune regole pratiche per non ritrovarti in un caso simile:

  • Conserva le Application Password con il nome del sito nel campo «nota» del gestore di credenziali. Non solo «WordPress», ma «WordPress — sito-cliente.it — produzione».
  • Ogni ambiente — produzione, staging, sviluppo — ha credenziali separate, generate indipendentemente.
  • Quando rigeneri una password, aggiorna il sistema di automazione e testa la sonda immediatamente. Non «dopo».
  • Se il sito va su un nuovo hosting, verifica la sonda prima di considerare la migrazione completata. L’header Authorization è il primo a sparire in ambienti mal configurati.

Per una panoramica più ampia su come strutturare i controlli in un sistema di automazione, puoi leggere anche la guida completa a Make.com: gestire gli errori nei moduli è lo stesso principio applicato a un tool visuale.

Perché i report nativi mentono in questo contesto

WordPress ha un sistema di log degli errori. I plugin di sicurezza hanno dashboard dettagliate. L’hosting ha i propri log di accesso. Nessuno di questi strumenti ti avrebbe detto, in questo caso, che il problema era la credenziale sbagliata.

I log di accesso mostravano richieste 401 senza distinguere tra «header non arrivato» e «header arrivato ma credenziale errata». La dashboard di Wordfence non aveva bloccato nulla. Il pannello delle Application Password su WordPress mostrava la password come attiva. Tutto sembrava a posto. Niente era a posto.

Il silenzio dei sistemi non è salute. Quando tutto risponde normalmente ma il risultato è sbagliato, significa che nessuno dei monitor attivi è posizionato nel punto giusto. La sonda funziona perché misura esattamente la variabile che conta, non un proxy di essa.

Lo stesso principio vale per qualsiasi macchina di automazione. I report nativi di GoHighLevel, di Make, di n8n mostrano successi e fallimenti sul layer che controllano. Non vedono cosa succede tra un sistema e l’altro. Lì vivono la maggior parte dei problemi reali. Se vuoi capire come integrare queste logiche in un sistema più ampio, la guida a GoHighLevel e il capitolo sugli errori nei webhook sono un buon punto di partenza.

Il principio che resta

Un probe deterministico batte dieci ipotesi plausibili. Non perché le ipotesi siano sbagliate — in questo caso erano tutte tecnicamente possibili — ma perché ogni ipotesi aggiunge lavoro senza ridurre l’incertezza. La sonda fa l’opposto: isola una variabile, risponde in modo binario, chiude un ramo dell’albero.

Costruire questa abitudine nel debug API WordPress — e più in generale in qualsiasi integrazione tra sistemi — cambia il modo in cui passi il tempo. Non stai più applicando fix a caso e sperando. Stai raccogliendo dati. C’è una differenza enorme, e si misura in ore.

Domande frequenti

Perché WordPress restituisce 401 anche con le credenziali corrette?

Quasi sempre perché l’header Authorization non arriva a PHP. Apache in modalità CGI lo elimina per default. Aggiungi SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 al .htaccess. La sonda descritta nell’articolo conferma in trenta secondi se è questo il caso.

Le Application Password di WordPress funzionano su HTTP?

No. WordPress le disabilita automaticamente su connessioni non HTTPS. In locale o su staging senza certificato SSL valido, devi abilitarle esplicitamente con un filtro: add_filter( 'wp_is_application_passwords_available', '__return_true' );. In produzione, forza sempre HTTPS.

Come faccio a sapere se è Wordfence a bloccare le chiamate API?

Controlla il corpo della risposta, non solo il codice HTTP. Wordfence restituisce un HTML con il suo watermark nel body anche quando la risposta ha codice 403. In alternativa, disabilita temporaneamente il firewall e testa: se il 403 sparisce, era lui.

La sonda debug va lasciata attiva in produzione?

No. È uno strumento di diagnosi, non una route permanente. Aggiungila quando serve, rimuovila appena hai il dato che ti serve. Lasciare in produzione un endpoint senza autenticazione che espone informazioni sull’header è un rischio inutile.

Iscriviti GRATIS a Gohighlevel

Il miglior software per scalare il tuo business. Se mi contatti dopo la prova gratuita dimostrando che ti sei iscritto con il mio link, hai una consulenza gratuita.

Hai domande?

Ogni tuo dubbio è un’opportunità per me di aiutarti.

Angelo Marcoccia

CHI SONO

Ho passato gli ultimi anni a costruire i sistemi che hanno portato un business da zero a oltre un milione di euro al mese — acquisizione, vendita, delivery e dati, tutto automatizzato. Oggi progetto gli stessi sistemi per infobusiness e agenzie che vogliono crescere senza esplodere di operatività. Quello che consiglio, lo so costruire con le mie mani.

INIZIA A CAPIRCI QUALCOSA

Mettiamoci in contatto

LEGGI IL BLOG SUlle automazioni

AUTOMATIZzA IL TUO BUSINESS