Webhook · Sicurezza · HMAC
Validare le firme dei webhook in entrata: Shopify, eBay e Stripe
Un webhook è una richiesta HTTP che arriva da Internet: prima di fidarti del contenuto devi verificarne la firma, altrimenti chiunque può inviare eventi falsi al tuo endpoint. Shopify, eBay e Stripe lo fanno in modo simile nei principi ma diverso nei dettagli. Questa guida mette a confronto i tre approcci con un esempio in .NET su Azure.
La regola comune
- calcola la firma sul body grezzo (i byte ricevuti), non sull'oggetto JSON già parsato;
- confronta con un confronto a tempo costante per evitare timing attack;
- se non combacia rispondi
401e non fare nulla; se combacia rispondi200e processa in modo asincrono; - conserva il segreto di firma fuori dal codice.
Esempio in .NET (HMAC-SHA256)
// rawBody = i byte ESATTI della richiesta (niente re-serializzazione)
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signingSecret));
byte[] computed = hmac.ComputeHash(rawBody);
byte[] received = Convert.FromBase64String(headerValue); // Shopify: base64
bool ok = CryptographicOperations.FixedTimeEquals(computed, received); // tempo costante
if (!ok) return Results.Unauthorized();
// ... accoda l'elaborazione e rispondi 200
Per Stripe la firma è in esadecimale e si calcola su timestamp + "." + payload; il resto del flusso è identico.
Le differenze per piattaforma
| Piattaforma | Header | Meccanismo |
|---|---|---|
| Shopify | X-Shopify-Hmac-Sha256 | HMAC-SHA256 in base64 con il client secret, sul body grezzo |
| Stripe | Stripe-Signature | HMAC-SHA256 in hex su timestamp+payload, con tolleranza sul timestamp |
| eBay (account deletion) | x-ebay-signature | Hash SHA-256 per il challenge e validazione della firma con la chiave pubblica eBay |
Quindi Shopify e Stripe usano un segreto condiviso (HMAC); eBay, per le notifiche di cancellazione account, usa una firma verificabile con chiave pubblica. I dettagli del flusso eBay sono nella guida sul webhook di cancellazione account eBay, mentre per i webhook Shopify vedi la guida sui webhook di conformità GDPR di Shopify.
Conservare i segreti
La verifica vale solo se il segreto resta segreto: tienilo in un secret manager con identità gestita, come descritto in come proteggere segreti e credenziali con Azure Key Vault, e ruotalo periodicamente.
Errori comuni
- calcolare la firma sul JSON parsato invece che sul body grezzo;
- usare un confronto stringa normale invece che a tempo costante;
- ignorare la tolleranza sul timestamp (Stripe) e accettare richieste vecchie (replay);
- segreto di firma hardcoded nel codice o nei log.
Conclusione
Validare le firme è poche righe di codice, ma sbagliarle espone l'endpoint a eventi falsi. La ricetta è sempre la stessa: body grezzo, confronto a tempo costante, 200/401, segreto protetto. Riferimenti: webhook HTTPS (Shopify) e webhook signatures (Stripe).