Validar solicitações da HubSpot

Para garantir que as solicitações que sua integração esteja recebendo da HubSpot venham realmente da HubSpot, vários cabeçalhos são preenchidos na solicitação. Você pode usar esses cabeçalhos, juntamente com os campos da solicitação recebida, para verificar a assinatura da solicitação.

O método usado para verificar a assinatura depende da versão da assinatura.

  • Para validar uma solicitação usando a versão mais recente da assinatura do HubSpot, use o cabeçalho X-HubSpot-Signature-V3 e siga as instruções associadas para validar a versão v3 da assinatura.
  • Para compatibilidade com versões anteriores, as solicitações do HubSpot também incluem versões mais antigas da assinatura. Para validar uma versão mais antiga da assinatura, verifique o cabeçalho X-HubSpot-Signature-Version e siga as instruções associadas abaixo com base em se a versão é v1 ou v2.

Nas instruções abaixo, saiba como derivar um valor de hash do segredo do cliente do seu aplicativo e dos campos de uma solicitação recebida. Depois de calcular o valor do hash, você o comparará à assinatura. Se os dois forem iguais, a solicitação passará na validação. Caso contrário, a solicitação pode ter sido alterada em trânsito ou alguém pode estar falsificando solicitações para seu endpoint.

Validar solicitações usando a assinatura de solicitação v1

Se seu aplicativo estiver inscrito em eventos de objetos do CRM por meio da API do webhooks, as solicitações do HubSpot serão enviadas com o cabeçalho X-HubSpot-Signature-Version definido como v1. O cabeçalho X-HubSpot-Signature será um hash SHA-256 gerado usando o segredo do cliente do seu aplicativo combinado com detalhes da solicitação.

Para verificar a versão da assinatura, siga as seguintes etapas:

  • Crie uma string que concatena o seguinte: Client secret request body (se estiver presente)
  • Crie um hash SHA-256 da string resultante.
  • Compare o valor do hash com o valor do cabeçalho X-HubSpot-Signature:
    • Se forem iguais, essa solicitação passou na validação.
    • Se esses valores forem diferentes, essa solicitação pode ter sido alterada em trânsito ou alguém pode ter falsificado solicitações no seu endpoint.

Exemplo de uma solicitação com um corpo:

//Client secret : yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy // Request body: [ {"eventId":1,"subscriptionId":12345," portalId":62515", occurredAt":1564113600000", subscriptionType":"contact.creation", "attemptNumber":0, "objectId":123, "changeSource":"CRM", "changeFlag":"NEW", "appId":54321} ]

Exemplos de assinatura de solicitação v1: 

NOTE: This is only an example for generating the expected hash. You will need to compare this expected hash with the actual hash in the X-HubSpot-Signature header. >>> import hashlib >>> client_secret = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' >>> request_body = '[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' >>> source_string = client_secret + request_body >>> source_string 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' >>> hashlib.sha256(source_string).hexdigest() '232db2615f3d666fe21a8ec971ac7b5402d33b9a925784df3ca654d05f4817de' NOTE: This is only an example for generating the expected hash. You will need to compare this expected hash with the actual hash in the X-HubSpot-Signature header. irb(main):003:0> require 'digest' => true irb(main):004:0> client_secret = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' => "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" irb(main):005:0> request_body = '[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' => "[{\"eventId\":1,\"subscriptionId\":12345,\"portalId\":62515,\"occurredAt\":1564113600000,\"subscriptionType\":\"contact.creation\",\"attemptNumber\":0,\"objectId\":123,\"changeSource\":\"CRM\",\"changeFlag\":\"NEW\",\"appId\":54321}]" irb(main):006:0> source_string = client_secret + request_body => "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy[{\"eventId\":1,\"subscriptionId\":12345,\"portalId\":62515,\"occurredAt\":1564113600000,\"subscriptionType\":\"contact.creation\",\"attemptNumber\":0,\"objectId\":123,\"changeSource\":\"CRM\",\"changeFlag\":\"NEW\",\"appId\":54321}]" irb(main):007:0> Digest::SHA256.hexdigest source_string => "232db2615f3d666fe21a8ec971ac7b5402d33b9a925784df3ca654d05f4817de" NOTE: This is only an example for generating the expected hash. You will need to compare this expected hash with the actual hash in the X-HubSpot-Signature header. > const crypto = require('crypto') undefined > client_secret = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' > request_body = '[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' '[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' > source_string = client_secret + request_body 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy[{"eventId":1,"subscriptionId":12345,"portalId":62515,"occurredAt":1564113600000,"subscriptionType":"contact.creation","attemptNumber":0,"objectId":123,"changeSource":"CRM","changeFlag":"NEW","appId":54321}]' > hash = crypto.createHash('sha256').update(source_string).digest('hex') '232db2615f3d666fe21a8ec971ac7b5402d33b9a925784df3ca654d05f4817de'

O hash resultante seria:
232db2615f3d666fe21a8ec971ac7b5402d33b9a925784df3ca654d05f4817de

Validar solicitações usando a assinatura de solicitação v2

Se seu aplicativo gerencia dados de uma ação de webhook em um fluxo de trabalho ou se você estiver retornando dados para um cartão de CRM personalizado, a solicitação do HubSpot será enviada com o cabeçalho X-HubSpot-Signature-Version definido como v2. O cabeçalho X-HubSpot-Signature será um hash SHA-256 gerado usando o segredo do cliente do seu aplicativo combinado com detalhes da solicitação.

Para verificar essa assinatura, execute as seguintes etapas:

  • Crie uma string que concatena o seguinte: Client secret + http method + URI + request body (se estiver presente)
  • Crie um hash SHA-256 da string resultante.
  • Compare o valor do hash à assinatura.
    • Se forem iguais, essa solicitação passou na validação.
    • Se esses valores forem diferentes, essa solicitação pode ter sido alterada em trânsito ou alguém pode ter falsificado solicitações no seu endpoint.

Observações:
  • a URI usada para construir a string de origem deve corresponder exatamente à solicitação original, incluindo o protocolo. Se você tiver problemas para validar a assinatura, verifique se todos os parâmetros de consulta estão na mesma ordem em que foram listados na solicitação original.
  • A string de origem deve ser de codificado em UTF-8 antes de calcular o hash SHA-256.

Exemplo de uma solicitação GET:


Exemplo de uma solicitação com um corpo:

 

Validar assinaturas de solicitação v3

O cabeçalho X-HubSpot-Signature-v3 será um hash HMAC SHA-256 gerado usando o segredo do cliente do seu aplicativo combinado com detalhes da solicitação. Ela também conterá o cabeçalho X-HubSpot-Request-Timestamp.

Ao validar uma solicitação usando o cabeçalho X-HubSpot-Signature-v3, você precisará 

  • Rejeitar a solicitação se o registro de data/hora tiver mais de 5 minutos.
  • Na URI da solicitação, decodificar todos os caracteres codificados por URL listados na tabela abaixo. Você não precisa decodificar o ponto de interrogação que indica o início da string de consulta.
Valor codificado Valor decodificado
%3A :
%2F /
%3F ?
%40 @
%21 !
%24 $
%27 '
%28 (
%29 )
%2A *
%2C ,
%3B ;
  • Crie uma string codificada em utf-8 que concatena o seguinte: requestMethod + requestUri + requestBody + timestamp. O registro de data e hora é fornecido pelo cabeçalho X-HubSpot-Request-Timestamp.
  • Crie um hash HMAC SHA-256 da string resultante usando o segredo do aplicativo como o segredo da função HMAC SHA-256.
  • A Base64 codifica o resultado da função do HMAC.
  • Compare o valor do hash à assinatura. Se forem iguais, a origem da solicitação foi confirmada como sendo da HubSpot. É recomendado usar uma comparação de string de tempo constante para proteger contra ataques de sincronização.

Este artigo foi útil?
Este formulário deve ser usado apenas para fazer comentários sobre esses artigos. Saiba como obter ajuda para usar a HubSpot..