Validation des demandes par HubSpot

Pour vérifier que les demandes que votre intégration reçoit de HubSpot proviennent bien de HubSpot, plusieurs en-têtes sont renseignés dans la demande. Vous pouvez utiliser ces en-têtes ainsi que les champs de la demande entrante pour vérifier la signature de la demande.

La méthode utilisée pour vérifier la signature dépend de la version de la signature :

  • Pour valider une demande à l'aide de la dernière version de la signature HubSpot, utilisez l'en-tête X-HubSpot-Signature-V3 et suivez les  instructions associées pour valider la version 3 de la signature.
  • Pour la rétrocompatibilité, les demandes de HubSpot incluent également les anciennes versions de la signature. Pour valider une ancienne version de la signature, consultez l'en-tête X-HubSpot-Signature-Version, puis suivez les instructions associées ci-dessous selon la version v1 ou v2.

Dans les instructions ci-dessous, découvrez comment obtenir une valeur de hachage à partir du secret client de votre application et des champs d'une demande entrante. Une fois que vous calculez la valeur de hachage, vous la comparerez à la signature. Si les deux sont égales, la demande a été validée avec succès. Autrement, cette demande peut avoir été modifiée en transit ou quelqu'un peut usurper les demandes à votre point de terminaison.

Valider les demandes à l'aide de la signature de demande v1

Si votre application est abonnée aux événements d'objet CRM via l'API des webhooks, les demandes de HubSpot seront envoyées avec l'en-tête X-HubSpot-Signature-Version défini sur v1. L'en-tête X-HubSpot-Signature sera un hachage SHA-256 conçu à l'aide du secret client de votre application associé à des détails de la demande.

Pour vérifier la version de cette signature, effectuez les étapes suivantes :

  • Créez une chaîne qui regroupe les éléments suivants : clientSecret requestBody (le cas échéant)
  • Créez un hachage SHA-256 de la chaîne résultante.
  • Comparez la valeur de hachage à la valeur de l'en-tête X-HubSpot-Signature :
    • Si elle est égale, cette demande a été validée.
    • Si ces valeurs sont différentes, cette demande peut avoir été modifiée en transit ou quelqu'un peut usurper les demandes à votre point de terminaison.

Exemple de demande avec un corps :

//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} ]

Exemples de signatures de demande 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'

Le hachage résultant serait :
232db2615f3d666fe21a8ec971ac7b5402d33b9a925784df3ca654d05f4817de

Valider les demandes à l'aide de la signature de demande v2

Si votre application gère des données provenant d'une action de webhook dans un workflow ou si vous renvoyez des données pour une carte CRM personnalisée, la demande de HubSpot est envoyée avec l'en-tête X-HubSpot-Signature-Version défini sur v2. L'en-tête X-HubSpot-Signature sera un hachage SHA-256 conçu à l'aide du secret de client de votre application associé à des détails de la demande.

Pour vérifier cette signature, effectuez les étapes suivantes :

  • Créez une chaîne qui regroupe les éléments suivants : secretClient + httpMethod + URI + requestBody (le cas échéant)
  • Créez un hachage SHA-256 de la chaîne résultante.
  • Comparez la valeur de hachage à la signature.
    • Si elle est égale, cette demande a été validée.
    • Si ces valeurs sont différentes, cette demande peut avoir été modifiée en transit ou quelqu'un peut usurper les demandes à votre point de terminaison.

Remarques :
  • L'URI utilisé pour créer la chaîne source doit correspondre exactement à la demande initiale, y compris le protocole. Si vous rencontrez des difficultés lors de la validation de la signature, assurez-vous que tous les paramètres de demande sont dans le même ordre que dans la demande initiale.
  • La chaîne source doit être encodée en UTF-8 avant de calculer le hachage SHA-256.

Exemple pour une demande GET :


Exemple de demande avec un corps :

 

Valider les signatures de demande v3

L'en-tête X-HubSpot-Signature-v3 sera un hachage HMAC SHA-256 composé du secret de client de votre application et des détails de la demande. Il comprendra également un en-tête X-HubSpot-Request-Timestamp.

Lors de la validation d'une demande à l'aide de l'en-tête X-HubSpot-Signature-v3, vous devrez 

  • Rejetez la demande si l'horodatage est supérieur à 5 minutes.
  • Dans l'URI de demande, décodez les caractères encodés en URL répertoriés dans le tableau ci-dessous. Vous n'avez pas besoin de décoder le point d'interrogation qui indique le début de la chaîne de demande.
Valeur encodée Valeur décodée
%3A :
%2F /
%3F ?
%40 @
%21 !
%24 $
%27 '
%28 (
%29 )
%2A *
%2C ,
%3B ;
  • Créez une chaîne encodée en UFT-8 qui regroupe les éléments suivants : requestMethod + requestUri + requestBody + horodatage. L'horodatage est fourni par l'en-tête X-HubSpot-Request-Timestamp.
  • Créez un hachage HMAC SHA-256 de la chaîne résultante en utilisant le secret d'application comme secret pour la fonction HMAC SHA-256.
  • Encodez le résultat de la fonction HMAC en Base64.
  • Comparez la valeur de hachage à la signature. Si elle est égale, cette demande a été validée comme provenant de HubSpot. Il est recommandé d'utiliser une comparaison de chaîne à durée fixe pour éviter les attaques temporelles.

Cet article vous a-t-il été utile ?
Ce formulaire est destiné à recueillir les avis sur la documentation pour les développeurs. Si vous souhaitez faire part de votre avis sur les produits HubSpot, veuillez le partager sur le forum des idéesde la communauté.