Verificación de firmas
DiffHook firma cada carga útil de webhook para que puedas verificar que proviene de nosotros y que no fue manipulada.
como funciona
Cada solicitud incluye un encabezado X-Signature que contiene una firma HMAC-SHA256 del cuerpo de la solicitud sin formato, con el prefijo sha256=.
X-Signature: sha256=abc123def456...
Su secreto de firma está disponible en Aplicación → Configuración → Claves API.
Verificando en Node.js
Utilice express.raw() para capturar los bytes del cuerpo sin formato antes de cualquier análisis JSON. Calcular la firma sobre un objeto reserializado producirá un hash diferente.
const crypto = require('crypto')
function verifySignature(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody) // raw Buffer — not JSON.stringify(req.body)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
// Mount with express.raw() so req.body is the raw Buffer
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['X-Signature']
if (!signature || !verifySignature(req.body, signature, process.env.DIFFHOOK_SIGNING_SECRET)) {
return res.status(401).send('Invalid signature')
}
res.status(200).send('OK')
const event = JSON.parse(req.body)
// process event...
})
Verificando en Python
import hmac, hashlib, json
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
Notas importantes
- Utilice siempre
crypto.timingSafeEqual(o equivalente) para evitar ataques de sincronización - Calcule la firma a partir de los bytes sin procesar del cuerpo de la solicitud, antes del análisis JSON
- Si falta
X-Signature, rechace la solicitud.
Rotar su secreto de firma
Cambie su secreto de firma en Configuración en cualquier momento. Después de la rotación, las firmas antiguas fallarán: actualice su implementación antes de revocar el secreto antiguo.