Verificando assinaturas
O DiffHook assina cada carga útil do webhook para que você possa verificar se ela veio de nós e não foi adulterada.
Como funciona
Cada solicitação inclui um cabeçalho X-Signature contendo uma assinatura HMAC-SHA256 do corpo bruto da solicitação, prefixado com sha256=.
X-Signature: sha256=abc123def456...
Seu segredo de assinatura está disponível em Aplicativo → Configurações → Chaves de API.
Verificando em Node.js
Use express.raw() para capturar os bytes do corpo bruto antes de qualquer análise JSON. Calcular a assinatura em um objeto re-serializado produzirá um 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 em 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
- Sempre use
crypto.timingSafeEqual(ou equivalente) para evitar ataques de temporização - Calcule a assinatura a partir dos bytes brutos do corpo da solicitação, antes da análise JSON
- Se
X-Signatureestiver faltando, rejeite a solicitação
Rotacionando seu segredo de assinatura
Alterne seu segredo de assinatura em Configurações a qualquer momento. Após a rotação, as assinaturas antigas falharão. Atualize sua implantação antes de revogar o segredo antigo.