Validar a assinatura

Como confirmar que o aviso veio de nós e não foi alterado no caminho.

Qualquer um que descubra a sua URL pode mandar um POST para ela. A assinatura é o que separa um aviso nosso de um falso.

Como funciona

  1. Pegue o segredo do canal no painel, em Notificações e logs (Mostrar / Gerar outro). Guarde no servidor, como PROJECT_WEBHOOK_SECRET.
  2. Calcule o HMAC-SHA256 de "{X-Project-Timestamp}.{corpo cru}" com o segredo, em hex, e ponha sha256= na frente.
  3. Compare com X-Project-Signature-256 em tempo constante.
  4. Recuse avisos com mais de 5 minutos (X-Project-Timestamp), para ninguém reaproveitar um aviso antigo.
  5. Guarde o id de cada aviso e ignore um que já processou.

Use o corpo cru

A assinatura é sobre os bytes exatos que chegaram. Converter para JSON e de volta para texto muda espaços e a ordem das chaves, e a assinatura deixa de bater — é o erro mais comum de quem integra webhook.

Exemplos

Node.js (Express)
const crypto = require('crypto');
const express = require('express');
const app = express();

// O corpo CRU (express.raw): a assinatura é sobre o texto exato que chegou.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const timestamp = req.get('X-Project-Timestamp') || '';
  const received = req.get('X-Project-Signature-256') || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.PROJECT_WEBHOOK_SECRET)
    .update(timestamp + '.' + req.body)
    .digest('hex');

  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  const recent = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
  if (!valid || !recent) return res.sendStatus(401);

  const event = JSON.parse(req.body);
  // event.id é o mesmo numa repetição: ignore o que já processou.
  res.sendStatus(204);
});

Trocar o segredo

Em Notificações e logs, Gerar outro cria um segredo novo para o canal. Atualize PROJECT_WEBHOOK_SECRET no seu servidor logo em seguida: a partir daí, os avisos chegam assinados com o segredo novo.

Nesta página