silver and gold rings on brown wooden table
Foto di Edz Norton su Unsplash

API Security

Webhook security: come proteggere le notifiche HTTP con firme HMAC e controlli anti-replay

20 October 2026 4 min lettura

I webhook sono uno degli strumenti più comodi per collegare applicazioni e servizi differenti.

Permettono di ricevere notifiche automatiche quando si verifica un evento, senza dover interrogare continuamente un'API.

Un e-commerce può ricevere una notifica quando un pagamento viene completato. Un gestionale può aggiornare lo stato di un ordine. Un'applicazione SaaS può reagire alla creazione di un nuovo account o a una modifica effettuata su una piattaforma esterna.

Tutto questo rende i webhook estremamente utili.

Ma c'è un aspetto da considerare: come possiamo essere sicuri che una notifica HTTP provenga realmente dal servizio che dichiara di averla inviata?

Se un endpoint webhook accetta qualsiasi richiesta senza verificarne l'autenticità, un attaccante potrebbe tentare di inviare eventi falsi.

Vediamo come proteggere i webhook e quali errori evitare durante l'implementazione.

Che cos'è un webhook?

Un webhook è un meccanismo attraverso il quale un'applicazione invia automaticamente una richiesta HTTP a un'altra applicazione quando si verifica un evento.

A differenza di una normale chiamata API, che viene avviata dal client quando ha bisogno di informazioni, il webhook viene generalmente inviato dal servizio che produce l'evento.

Immaginiamo un negozio online che utilizza un provider di pagamento.

Quando un cliente completa una transazione, il provider può inviare una richiesta a un endpoint del negozio:

https://example.com/webhooks/payment

Il server riceve la notifica e aggiorna lo stato dell'ordine.

Questo evita di dover controllare continuamente se il pagamento è stato completato.

Come funziona un webhook nella pratica?

Il flusso tipico comprende alcuni passaggi.

  1. L'applicazione registra un endpoint presso il servizio esterno.
  2. Si verifica un evento, per esempio un pagamento.
  3. Il servizio invia una richiesta HTTP all'endpoint.
  4. L'applicazione ricevente verifica la richiesta.
  5. Se l'evento è valido, esegue l'operazione prevista.
  6. Il server restituisce una risposta HTTP.

Una richiesta potrebbe contenere un payload JSON simile:

{
  "event_id": "evt_12345",
  "type": "payment.completed",
  "data": {
    "order_id": "ORD-987",
    "amount": 4990,
    "currency": "EUR"
  }
}

Il formato effettivo dipende dal provider.

Il campo amount, in questo esempio, rappresenta un importo in unità minori della valuta, ma anche questa convenzione deve essere verificata nella documentazione del servizio utilizzato.

Perché i webhook possono essere un rischio?

Un endpoint webhook è spesso raggiungibile pubblicamente.

Questo significa che, in assenza di protezioni, chiunque potrebbe tentare di inviare una richiesta HTTP all'indirizzo.

Immaginiamo che un'applicazione aggiorni lo stato di un ordine semplicemente leggendo il campo:

{
  "type": "payment.completed",
  "data": {
    "order_id": "ORD-987"
  }
}

Se non viene verificata l'autenticità della richiesta, un attaccante potrebbe tentare di inviare un evento costruito artificialmente.

Il sistema potrebbe interpretarlo come una conferma di pagamento legittima.

Per questo motivo, non bisogna mai fidarsi di un webhook soltanto perché il suo contenuto sembra corretto.

Come verificare l'autenticità di un webhook

Molti provider utilizzano firme crittografiche per consentire al destinatario di verificare l'origine e l'integrità del messaggio.

Uno dei meccanismi più comuni è HMAC.

La sigla significa Hash-based Message Authentication Code.

In questo schema, mittente e destinatario condividono un segreto.

Il mittente calcola una firma utilizzando il contenuto della richiesta e il segreto condiviso.

Il destinatario ripete il calcolo e confronta il risultato con la firma ricevuta.

Se la verifica ha successo, il messaggio risulta compatibile con il segreto atteso e non appare modificato rispetto ai dati firmati.

Questo presuppone naturalmente che il segreto sia rimasto riservato.

Come funziona una firma HMAC?

Immaginiamo che il servizio invii un payload JSON.

Il mittente utilizza un segreto condiviso e un algoritmo come HMAC-SHA256 per generare una firma.

Il destinatario riceve il payload e la firma, per esempio attraverso un header HTTP.

La verifica segue questo principio:

Payload originale
       +
Segreto condiviso
       ↓
    HMAC-SHA256
       ↓
Firma calcolata
       ↓
Confronto con la firma ricevuta

Se le firme corrispondono, la richiesta supera il controllo crittografico.

Il formato esatto della firma, gli header utilizzati e i dati firmati cambiano da provider a provider.

È quindi fondamentale seguire la documentazione ufficiale del servizio.

Esempio di verifica HMAC in PHP

Consideriamo un esempio generico nel quale il provider invia una firma HMAC-SHA256 espressa in formato esadecimale attraverso l'header X-Webhook-Signature.

Il codice potrebbe essere:

<?php

$secret = getenv('WEBHOOK_SECRET');

if (!is_string($secret) || $secret === '') {
    http_response_code(500);
    exit('Configurazione non valida');
}

$payload = file_get_contents('php://input');

if ($payload === false) {
    http_response_code(400);
    exit('Payload non valido');
}

$receivedSignature =
    $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

$expectedSignature = hash_hmac(
    'sha256',
    $payload,
    $secret
);

if (
    !is_string($receivedSignature) ||
    !hash_equals(
        $expectedSignature,
        $receivedSignature
    )
) {
    http_response_code(401);
    exit('Firma non valida');
}

// La firma è valida.
// Proseguire con la validazione del payload.

Questo esempio mostra il principio generale.

Non deve essere copiato direttamente per un provider specifico senza verificare il formato previsto dalla sua documentazione.

Alcuni servizi includono timestamp, identificatori o prefissi nella stringa da firmare.

Altri utilizzano codifiche differenti.

Perché bisogna verificare il payload originale?

Un errore abbastanza comune consiste nel decodificare il JSON e poi ricodificarlo prima di calcolare la firma.

Il problema è che due rappresentazioni JSON possono contenere gli stessi dati ma avere sequenze di byte differenti.

Per esempio, spazi, ordine delle proprietà e caratteri di escape possono modificare il contenuto testuale.

Se la firma viene calcolata sui byte originali, qualsiasi trasformazione può provocare un errore di verifica.

Per questo motivo, bisogna generalmente utilizzare il corpo HTTP originale ricevuto, seguendo le specifiche del provider.

Che cos'è un replay attack?

Una firma valida non risolve automaticamente tutti i problemi.

Immaginiamo che un attaccante riesca a ottenere una richiesta webhook autentica.

Potrebbe tentare di inviarla nuovamente al server.

Questo comportamento viene chiamato replay attack.

La richiesta potrebbe avere una firma perfettamente valida, perché il contenuto non è stato modificato.

Il problema è che lo stesso evento viene ripresentato.

Se l'applicazione non gestisce correttamente i duplicati, potrebbe eseguire più volte la stessa operazione.

Come prevenire i replay attack

Una prima misura consiste nell'utilizzo di timestamp firmati.

Il servizio include nella firma anche il momento in cui la richiesta è stata generata.

Il destinatario verifica che il timestamp rientri in una finestra temporale accettabile.

Se la richiesta è troppo vecchia, viene rifiutata.

Tuttavia, questo meccanismo non elimina completamente il rischio di duplicati all'interno della finestra consentita.

Per questo motivo è utile gestire anche gli identificatori univoci degli eventi.

Idempotenza: perché è fondamentale nei webhook

Un'operazione è idempotente quando eseguirla più volte produce lo stesso effetto previsto di una singola esecuzione.

Nel contesto dei webhook, significa evitare che la ricezione ripetuta dello stesso evento provochi modifiche duplicate.

Supponiamo che un provider invii due volte la notifica di pagamento completato.

Il sistema non dovrebbe generare due spedizioni o registrare due accrediti per lo stesso evento.

Una soluzione consiste nel memorizzare gli identificatori degli eventi già elaborati.

Per esempio:

CREATE TABLE webhook_events (
    event_id VARCHAR(191) PRIMARY KEY,
    event_type VARCHAR(100) NOT NULL,
    processed_at DATETIME NOT NULL
);

Quando arriva una nuova notifica, l'applicazione verifica se l'identificatore è già stato gestito.

In un sistema reale, però, bisogna anche considerare la concorrenza.

Due richieste identiche potrebbero arrivare quasi contemporaneamente.

È quindi importante utilizzare vincoli univoci, transazioni e una logica di elaborazione che eviti operazioni duplicate anche in presenza di richieste simultanee.

I webhook devono utilizzare HTTPS?

Sì, gli endpoint webhook che ricevono dati attraverso Internet dovrebbero utilizzare HTTPS.

La connessione cifrata protegge il traffico durante il trasporto e contribuisce a ridurre il rischio di intercettazioni e manipolazioni.

Tuttavia, HTTPS non sostituisce la verifica della firma.

La cifratura della connessione e l'autenticazione del messaggio risolvono problemi differenti.

Entrambe le misure sono importanti.

È utile limitare gli indirizzi IP dei mittenti?

Alcuni provider pubblicano gli intervalli IP utilizzati per inviare webhook.

In questi casi, può essere utile consentire le richieste soltanto da tali indirizzi.

Questa misura può ridurre il numero di richieste indesiderate.

Non dovrebbe però essere considerata una sostituzione della verifica crittografica.

Gli intervalli IP possono cambiare e, in alcune architetture, le richieste possono attraversare proxy o altri componenti di rete.

È necessario mantenere aggiornate le regole e comprendere come il server identifica l'indirizzo IP reale del client.

Perché non bisogna elaborare tutto immediatamente

Un endpoint webhook dovrebbe rispondere in tempi ragionevoli.

Se l'elaborazione richiede operazioni lente, come generazione di documenti, chiamate ad altri servizi o aggiornamenti complessi, può essere preferibile utilizzare una coda.

Il flusso diventa:

  1. Ricezione della richiesta.
  2. Verifica della firma.
  3. Validazione dell'evento.
  4. Registrazione affidabile del messaggio.
  5. Risposta HTTP al provider.
  6. Elaborazione asincrona dell'evento.

In questo modo si riduce il rischio che il provider consideri la richiesta fallita a causa di un timeout.

Naturalmente, il messaggio deve essere registrato in modo durevole prima di confermare la ricezione.

Come proteggere un endpoint webhook dagli abusi

Oltre alla verifica delle firme, conviene applicare altre misure.

Tra queste:

  • Limitare la dimensione massima delle richieste.
  • Validare il formato e i campi del payload.
  • Gestire gli eventi sconosciuti senza eseguire operazioni.
  • Non registrare segreti nei log.
  • Utilizzare credenziali con privilegi limitati.
  • Monitorare gli errori di verifica.
  • Gestire i duplicati.
  • Impostare timeout per le operazioni esterne.

È importante anche evitare che il contenuto di un webhook venga utilizzato direttamente per costruire query SQL, comandi di sistema o richieste verso URL arbitrari.

Il fatto che un messaggio abbia una firma valida non significa che ogni suo campo possa essere utilizzato senza validazione.

Webhook e applicazioni SaaS

Nelle piattaforme SaaS, i webhook vengono spesso utilizzati per integrare sistemi di fatturazione, servizi di autenticazione, strumenti di monitoraggio e applicazioni di terze parti.

Una buona architettura dovrebbe prevedere segreti distinti per integrazione, controlli di autenticità, registrazione degli eventi e procedure per la rotazione delle credenziali.

È utile anche separare la ricezione del webhook dalla logica applicativa.

Questo rende più semplice effettuare test, gestire gli errori e individuare eventuali anomalie.

Come verificare la sicurezza dei webhook

Durante una revisione tecnica, è opportuno controllare che:

  • Le richieste non autenticate vengano rifiutate.
  • Le firme vengano verificate correttamente.
  • I segreti siano conservati fuori dal codice pubblico.
  • Gli eventi duplicati non producano effetti indesiderati.
  • Le richieste obsolete vengano gestite secondo le specifiche del provider.
  • I payload vengano validati.
  • Gli errori siano registrati senza divulgare informazioni sensibili.

I test devono essere effettuati esclusivamente su endpoint propri o per i quali si dispone di autorizzazione.

Conclusione

I webhook semplificano enormemente l'integrazione tra servizi, ma richiedono una progettazione attenta.

Un endpoint pubblico che accetta notifiche senza verificarne l'autenticità può diventare un punto debole dell'applicazione.

Firme HMAC, controlli anti-replay, idempotenza e validazione dei dati sono elementi fondamentali per costruire integrazioni affidabili.

La regola più importante è non considerare attendibile un evento soltanto perché arriva all'endpoint corretto.

Per approfondire puoi consultare la documentazione ufficiale del provider utilizzato e le indicazioni di OWASP sulla sicurezza delle API.

Con MiHakero puoi affiancare alla sicurezza delle integrazioni il monitoraggio delle esposizioni esterne dei tuoi servizi pubblici. La verifica delle firme e della logica dei webhook richiede invece controlli applicativi specifici.

SEO Meta Title: Webhook security: firme HMAC e protezione API

SEO Meta Description: Scopri come proteggere i webhook con firme HMAC, HTTPS, controlli anti-replay e idempotenza nelle applicazioni web e SaaS.

Testa la sicurezza del tuo sito

Avvia una scansione gratuita e scopri cosa la tua azienda espone online.

Prova Gratis

Prova MiHakero sulla tua azienda

Avvia una scansione gratuita e scopri cosa la tua azienda espone online.