Problema com o segredo do Webhook

Espero que alguém possa me dizer o que estou fazendo de errado aqui.

Configurei um Webhook do Discourse e ele funciona como esperado sem um Segredo. Em seguida, escrevo uma string no Segredo e, em seguida, copio essa string para o Webhook receptor como um Cabeçalho, assim:

X-Discourse-Event-Signature: segredo_aqui

Isso produz o seguinte erro no Corpo quando o webhook de envio é enviado:

{"code":"rest_forbidden","message":"Desculpe, você não tem permissão para fazer isso.","data":{"status":401}}

Espero que eu simplesmente não esteja fazendo isso certo, então, por favor, me ilumine!

Estou ciente de que o segredo é criptografado usando sha256, então o Cabeçalho que é enviado é:

X-Discourse-Event-Signature: sha256=XXX

Mas não tenho certeza do que devo fazer com essa informação nos Cabeçalhos de Segurança do Webhook receptor.

Não tenho certeza se é apenas a forma como você está escrevendo a postagem, mas o cabeçalho real seria

X-Discourse-Event-Signature: XXX

Você pode (opcionalmente) usar isso no lado receptor para validar que o webhook foi realmente enviado pelo Discourse. Se você não fizer a verificação, uma parte maliciosa poderá forjar eventos de webhook.

O que isso significa?

1 curtida

Então você está sugerindo que a Assinatura no webhook de recebimento deve ser o segredo criptografado, e NÃO o segredo escolhido não criptografado?

Eu estou de fato escrevendo o Cabeçalho no aplicativo de recebimento assim:
X-Discourse-Event-Signature: XXX

No entanto, continuo recebendo um erro 401 proibido ao usar um Segredo.

De onde é essa captura de tela?
Talvez você possa dar mais detalhes sobre sua configuração.

Meu site WordPress. Estou usando um Plugin do WordPress para receber Webhooks. Se eu não adicionar um Cabeçalho de Segurança (Segredo), o Webhook funciona bem. É apenas quando adiciono o segredo que o problema ocorre.

Aqui está o plugin: Incoming Webhook Triggers - Uncanny Automator

Obrigado pelo seu tempo, Richard!

1 curtida

Eu desde então restrinji o problema:

Cabeçalhos de segurança personalizados podem ser incluídos no gatilho do webhook de entrada, mas uma nota importante é como o WordPress pode alterar hífens para sublinhados. Como exemplo, tentar usar “x-api-key” pode exigir o uso de “x_api_key” em vez disso.

Tenho uma pergunta relacionada, no entanto, @RGJ. Vamos supor que meu segredo seja “1234”. No webhook de recebimento, o valor de X-Discourse-Event-Signature deve ser:

  1. 1234;
  2. sha256=encrypted_value_here;
  3. encrypted_value_here

?

É o nº 2, sha256=XXX.

Parece que o plugin do Wordpress que você está usando só pode comparar com um valor de cabeçalho estático, não com uma assinatura dinâmica. Isso é algo específico do Discourse.

1 curtida

Dê uma olhada em como o plugin WP Discourse lida com o segredo:

5 curtidas

Descobri desde então que o valor sha muda toda vez que o webhook é enviado, então colocar o valor sha no webhook receptor não funcionaria. Eu pensaria que teria que ser o exemplo nº 1, e como acho que você está sugerindo (cabeçalho estático), o plugin realmente precisaria decodificar o hash antes de gerar a resposta do cabeçalho?

Em conclusão, não acho que posso usar o X-Discourse-Event-Signature com hash neste plugin, porque ele só aceitará valores estáticos.

É inseguro usar um webhook sem um segredo? Eu estaria enviando Eventos de Usuário do meu Discourse para meu site principal, usando uma URL não óbvia como main-site.com/wp-json/fol/fil/532563-5312534. Eu também posso adicionar cabeçalhos estáticos que devem corresponder no hook receptor.

Você poderia me dar um exemplo de uma aplicação que poderia lidar com um hmac dinamicamente em mudança?

O valor é calculado em relação à carga útil do webhook, portanto, será diferente para cada solicitação.

Essa é uma pergunta interessante. O único aplicativo que conheço é o plugin WP Discourse, mas ele foi configurado especificamente para lidar com webhooks do Discourse. Se a implementação do Discourse estiver impedindo as pessoas de validar webhooks com segredos, talvez isso precise ser investigado.

Deixarei que outros respondam a isso.

Se você está preocupado em não validar o webhook, talvez o plugin Incoming Webhook Triggers tenha um hook de ação em seu código de recebimento de webhook que é acionado antes que os dados do webhook sejam processados. Se tiver, deve ser possível escrever uma função que se conecte a ele, verifique se os dados são para um webhook do Discourse e, em seguida, valide o segredo com algo como o código que linkei em minha postagem anterior.

2 curtidas

Fiquei curioso, então investiguei um pouco. Não tenho certeza sobre aplicativos que são configurados para lidar com o recebimento de uma assinatura HMAC em constante mudança, mas autenticar requisições de webhook com uma assinatura HMAC calculada contra a carga útil é uma prática bastante padrão para aplicativos que estão enviando webhooks. Por exemplo, GitHub, Stripe e Shopify usam esse método.

Existem também vários aplicativos populares que usam o método de token secreto de autenticação de webhooks. Por exemplo (em 2021) Mailchimp, Trello, Slack e Discord usam essa abordagem. Parece que o Slack ainda está usando esse método: Slack developer FAQ | Slack Developer Docs. Posso ver como isso tornaria as coisas mais fáceis para o aplicativo que recebe o webhook.

Acho que há um equilíbrio entre segurança e conveniência em termos de decidir qual método o aplicativo remetente usará. Minha preocupação com o método de assinatura HMAC do Discourse é que isso pode levar as pessoas a configurar webhooks sem chaves secretas para contornar a dificuldade de lidar com as assinaturas HMAC em constante mudança. Por exemplo, existem algumas referências no Meta para enviar webhooks do Discourse para o Zapier sem menção de como validar a assinatura no Zapier. (Deve ser tecnicamente possível validar as assinaturas no Zapier, no entanto. No momento, não estou configurado para testar isso.)

2 curtidas

Concordo plenamente com isso. Talvez isso seja algo que os desenvolvedores possam explorar - um método mais fácil e compatível de proteger dados de webhook.

Além disso, não tenho tanta certeza de que o Zapier seja capaz de validar a assinatura.

O recurso de segredo de webhook é implementado de acordo com isto:

Parece que o software que você deseja não suporta este recurso padrão de comunicação de segurança, mas você ainda pode utilizar webhooks do Discourse sem ele.

Não há planos para adicionar um cabeçalho fixo com um segredo compartilhado, pois o valor de segurança disso é questionável. No entanto, se você precisar disso, isso deve ser viável em um plugin.

4 curtidas