Une fois que votre serveur est configuré pour recevoir des charges utiles, il écoute toutes les charges utiles envoyées au point de terminaison que vous avez configuré. Pour des raisons de sécurité, vous pouvez limiter les demandes à celles envoyées par GitHub. Il existe plusieurs moyens de le faire (par exemple, vous pouvez choisir d’autoriser les demandes envoyées par l’adresse IP de GitHub), mais la méthode la plus facile est de configurer un jeton secret et de valider les informations.
Vous pouvez utiliser l’API REST pour gérer les webhooks de dépôt, d’organisation et d’application. Vous pouvez lister les livraisons d’un webhook, ou obtenir et refaire une livraison individuelle d’un webhook, qui peut être intégré dans une application ou un service externe. Vous pouvez également utiliser l’API REST pour changer la configuration du webhook. Par exemple, vous pouvez modifier l’URL de charge utile, le type de contenu, la vérification SSL et le secret. Pour plus d'informations, consultez les pages suivantes :
Définition de votre jeton secret
Vous devez configurer votre jeton secret à deux endroits : GitHub et votre serveur.
Pour définir votre jeton sur GitHub :
-
Accédez au dépôt dans lequel vous avez configuré votre webhook.
-
Sous le nom de votre dépôt, cliquez sur Paramètres. Si vous ne voyez pas l’onglet « Paramètres », sélectionnez le menu déroulant et cliquez sur Paramètres.
-
Dans la barre latérale gauche, cliquez sur Webhooks.
-
À côté du webhook, cliquez sur Modifier.
-
Dans le champ « Secret », tapez une chaîne aléatoire avec une entropie élevée. Vous pouvez générer une chaîne avec
ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'
dans le Terminal, par exemple. -
Cliquez sur Mettre à jour le webhook.
Ensuite, configurez une variable d’environnement sur votre serveur pour stocker ce jeton. En règle générale, ça revient à simplement exécuter :
$ export SECRET_TOKEN=YOUR-TOKEN
Ne codez jamais en dur le jeton dans votre application !
Validation des charges utiles provenant de GitHub
Quand votre jeton secret est défini, GitHub Enterprise Server l’utilise pour créer une signature de hachage avec chaque charge utile. Cette signature de hachage est ajoutée aux en-têtes de chaque demande sous la forme x-hub-signature-256
.
Remarque : Pour la compatibilité descendante, nous ajoutons également l’en-tête x-hub-signature
qui est généré avec la fonction de hachage SHA-1. Si possible, nous vous recommandons d’utiliser l’en-tête x-hub-signature-256
pour améliorer la sécurité. L’exemple ci-dessous montre l’utilisation de l’en-tête x-hub-signature-256
.
Par exemple, si vous avez un serveur de base qui écoute des webhooks, il peut être configuré de la façon suivante :
require 'sinatra'
require 'json'
post '/payload' do
request.body.rewind
push = JSON.parse(request.body.read)
"I got some JSON: #{push.inspect}"
end
L’intention est de calculer un hachage en utilisant votre SECRET_TOKEN
et de vérifier que le résultat correspond au hachage de GitHub Enterprise Server. GitHub Enterprise Server utilise un code de hachage hexadécimal HMAC pour calculer le hachage, vous pouvez donc reconfigurer votre serveur pour qu’il ressemble un peu à ceci :
post '/payload' do
request.body.rewind
payload_body = request.body.read
verify_signature(payload_body)
push = JSON.parse(payload_body)
"I got some JSON: #{push.inspect}"
end
def verify_signature(payload_body)
signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ENV['SECRET_TOKEN'], payload_body)
return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE_256'])
end
Remarque : Les charges utiles de webhook peuvent contenir des caractères Unicode. Si votre implémentation de langage et de serveur spécifie un codage de caractères, vérifiez que vous traitez la charge utile en UTF-8.
Vos implémentations de langage et de serveur peuvent différer de cet exemple de code. Toutefois, il y a un certain nombre de choses très importantes à souligner :
-
Quelle que soit l’implémentation que vous utilisez, la signature de hachage commence par
sha256=
, et utilise la clé de votre jeton secret et le corps de votre charge utile. -
L’utilisation d’un opérateur
==
brut n’est pas recommandée. Une méthode commesecure_compare
effectue une comparaison de chaînes de « temps constant », qui permet d’atténuer certaines attaques de minutage contre les opérateurs d’égalité classiques.