Verificar a assinatura

Cada entrega é assinada com o signing secret do endpoint (pwhsec_…), do jeito que a Stripe assina as dela.

O header

Headers
X-Pay-Signature: t=<unix time>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>
X-Pay-Event-Id:  <uuid, the same on a resend>

Verifique

Ruby
t, v1 = request.headers["X-Pay-Signature"].scan(/t=(\d+),v1=(\h+)/).first
body = request.raw_post
expected = OpenSSL::HMAC.hexdigest("SHA256", ENV["PAY_WEBHOOK_SECRET"], "#{t}.#{body}")

head :unauthorized unless ActiveSupport::SecurityUtils.secure_compare(expected, v1.to_s)
head :unauthorized if (Time.now.to_i - t.to_i).abs > 300
Node
import crypto from "node:crypto"

const [, t, v1] = req.get("X-Pay-Signature").match(/t=(\d+),v1=([0-9a-f]+)/)
const expected = crypto.createHmac("sha256", process.env.PAY_WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`).digest("hex")

const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
  && Math.abs(Date.now() / 1000 - Number(t)) <= 300

Lembre-se

  1. 1Assine o body cru exatamente como chegou; fazer parse e serializar o JSON de novo muda o conteúdo.
  2. 2Compare em tempo constante e recuse timestamps com mais de 5 minutos.
  3. 3Trocar o secret na página do app desativa o antigo na hora.

Tem certeza?

Atalhos de teclado

⌘ KBuscar e navegar⌘ JAbrir e fechar o Workbenchg hIníciog pPagamentosg cClientesg sSubscriptionsg aAppsg gGateways?Esta listaEscFechar