17-webhook-security
My SDK verifies webhooks two different ways. Most SDKs only do one.

My SDK verifies webhooks two different ways. Most SDKs only do one.
The eupago gateway offers two webhook formats: HMAC-SHA256 signed cleartext, and AES-256-CBC encrypted bodies. They're not "one or the other" — different merchants use different setups, and you only know which you'll receive when it lands.
In eupago-python both are first-class:
→ For HMAC signed webhooks: signature verification with constant-time compare. Not == on hex strings (that leaks timing). hmac.compare_digest, which is what hmac exists for.
→ For AES encrypted webhooks: derive the AES key from the webhook secret (SHA-256), pull the IV from the X-Initialization-Vector header, decrypt with PKCS7 padding. Then verify amount and currency match what you stored when you created the payment — signature valid is not business valid.
→ For both: dedup on a stable hash of the raw body so a re-delivery becomes a no-op.
"Just verify HMAC" is the README example everywhere. Production has more shapes.
If your webhook handler does == on hex strings, swap it for hmac.compare_digest before lunch. Easiest security win you can buy.
What's the security check your codebase ships without?
Repo: github.com/bilouro/eupago-python · Security docs: eupago.bilouro.com/security
P.S. New tech post every Wednesday.
#OpenSource #Python #SoftwareArchitecture
Comments