[GO] Jouez avec le mécanisme de mot de passe de GitHub Webhook et Python

secret.png

Quel est ce champ secret heureux (゜ ∀ ゜)

J'ai récemment le sentiment que cela a été saisi. Je vais écrire le processus que j'ai essayé approximativement. Veuillez signaler toute erreur.

Quel genre de fonction

En bref, GitHub vous enverra la signature de la charge utile.

Le résultat de HMAC (hachage à clé) la charge utile JSON envoyée à l'aide de cette clé C'est un mécanisme qui s'insère dans l'en-tête HTTP de WebHook. Le secret n'est pas visible sur l'écran GitHub après l'entrée, et il n'apparaît pas brut dans les données HTTP après cela, ce qui est également un peu sûr.

Vous pouvez rentrer

Je pense que ce mécanisme n'existait pas dans le passé. Probablement pas juste après le renouvellement du WebHook. Quand es-tu entré

Référence: http://blog.manaten.net/entry/573

En regardant la page ci-dessus, je ressens l'importance de la préservation de l'information. Il n'y a pas de champ de mot de passe, je le mets moi-même dans la chaîne de requête. C'était il y a un an.

Ce qui me rend heureux

Vous pouvez facilement augmenter le niveau de sécurité.

Vous pouvez essentiellement POSTER sur l'URL du WebHook et vous ne pouvez pas incorporer de jetons CSRF. Chaque fois que j'écris `` @ csrf_exempt``` dans Django, la valeur SAN diminue, mais cela ne peut pas être aidé.

Pour le moment, la bouche de WebHook semble être capable d'appliquer librement les restrictions IP, je vais donc l'utiliser. Pourtant, on craint que quelque chose provienne du projet malveillant GitHub. Il semble que toutes ou une quantité considérable d'informations envoyées puissent être déguisées (bien que je ne les ai pas examinées).

Donc je voulais en fait une clé autre que l'URL. Mais je ne veux pas écrire l'implémentation par moi-même (les personnes sur le site ci-dessus l'écrivent elles-mêmes, n'est-ce pas?)

Quel genre de comportement

Lorsque GitHub envoie un WebHook, il convertit la chaîne de sa charge utile JSON en un hachage de 40 caractères avec HMAC + sha1 à l'aide de key. Ainsi, lors de l'envoi de HTTP POST, une chaîne de caractères comme sha1 = dd671d65f5aee8c8aba748fd8f0143c10c5ba875 '' est insérée dans l'en-tête. Le serveur (vous-même) recevra la charge utile et sa «signature».

Le destinataire, ou votre propre serveur, peut vérifier la signature en convertissant la chaîne JSON envoyée à l'aide de la clé commune en un hachage avec le même algorithme. Si la signature est erronée, vous pouvez envoyer un avertissement à l'administrateur car c'est correct.

Ce n'est peut-être pas trop difficile s'il s'agit d'un langage de script avec un wrapper OpenSSL, et puisque les algorithmes eux-mêmes pour HMAC et sha1 sont normaux, vous pouvez probablement les vérifier avec le shell (ce qui signifie que vous n'utilisez pas `` sha1sum '' Je ne vais pas l'essayer, je ne l'essayerai jamais).

Il semble que la bibliothèque soit utilisée telle quelle même dans l'implémentation (apparemment) de Ruby utilisée par GitHub lui-même.

C'est aussi en Python. Un goût délibéré de Python.

Utilisons-le avec Python (+ Django)

Afin de recevoir la charge utile JSON, préparez deux types de soucoupes en fonction du Content-Type côté serveur. Cela en soi est quelque chose à mettre en œuvre indépendamment de cette histoire.

Il extrait également la chaîne de caractères envoyée via `` request.META.get ('HTTP_X_HUB_SIGNATURE') ''.

S'il est vide, il n'y a pas de mot de passe. S'il n'est pas vide, insérez la chaîne de charge utile brute dans hmac / hashlib.sha1 et générez vous-même un hachage à clé pour voir si c'est la même chose.

import hashlib
import hmac

...

    if content_type == 'application/json':
        payload = request.body
    else:
        payload = request.POST.get('payload')
    signature = request.META.get('HTTP_X_HUB_SIGNATURE')
    if signature:
        hasher = hmac.new(secret, payload, hashlib.sha1)
        logger.debug('Signature : {}'.format(signature))
        logger.debug('Calculated: sha1={}'.format(hasher.hexdigest()))

Je pense que c'est bien parce que les résultats des calculs sont corrects à portée de main.

Cependant, je ne suis pas sûr que le codage et le code de saut de ligne correspondent toujours à chaque fois. Si vous avez des détails, veuillez commenter.

prime

Je ne veux pas me souvenir de la clé brute côté serveur, mais si vous connaissez un moyen simple et efficace, veuillez me le faire savoir. Je me demande s'il est facile de sauvegarder le sérialisé avec Django ...

Postscript: lors du test avec django.test.Client

Si la charge utile elle-même est prête sous forme de chaîne, tout ce que vous avez à faire est de visser le résultat généré ci-dessus dans l'équivalent d'en-tête. Dans Django 1.6.5, il peut être incorporé comme suit.

        hasher = hmac.new('TestSecret', payload_str, hashlib.sha1)
        response = self.client.post(
            url, data={'payload': payload_str},
            HTTP_X_HUB_SIGNATURE='sha1={}'.format(hasher.hexdigest()))

C'est django 1.6.5, mais si vous définissez "application / x-www-form-urlencoded" qui peut être sélectionné sur GitHub comme content_type pour Client, vous ne pourrez pas recevoir de données POST avec response.POST.get ('...'). Il semble y avoir un problème. À propos de content_type Rendons possible la réception de données multipart / form-data côté serveur également. GitHub pourrait bientôt changer beaucoup de choses.

Recommended Posts

Jouez avec le mécanisme de mot de passe de GitHub Webhook et Python
Visualisez la gamme d'insertions internes et externes avec python
Jouons avec Python Receive et enregistrez / affichez le texte du formulaire de saisie
L'histoire de Python et l'histoire de NaN
Coexistence de Python2 et 3 avec CircleCI (1.0)
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
[Objet obligatoire DI] Implémenter et comprendre le mécanisme de DI avec Go
Vérifier l'existence du fichier avec python
Jouez avec 2016-Python
J'ai remplacé le calcul numérique de Python par Rust et comparé la vitesse
Calculer l'itinéraire le plus court d'un graphe avec la méthode Dyxtra et Python
Obtenez des visites d'articles et des likes avec l'API Qiita + Python
Obtenez et estimez la forme de la tête en utilisant Dlib et OpenCV avec python
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
Préparer l'environnement d'exécution de Python3 avec Docker
Résumé des différences entre PHP et Python
Mathématiques Todai 2016 résolues avec Python
[Note] Exportez le html du site avec python.
La réponse de "1/2" est différente entre python2 et 3
Calculez le nombre total de combinaisons avec python
Spécification de la plage des tableaux ruby et python
Comparez la vitesse d'ajout et de carte Python
Implémentation de l'arbre TRIE avec Python et LOUDS
Résolution du modèle Lorenz 96 avec Julia et Python
Archivez et compressez tout le répertoire avec python
Convertir le code de caractère du fichier avec Python3
Prise en compte des forces et faiblesses de Python
[Python] Déterminez le type d'iris avec SVM
Exemple de lecture et d'écriture de CSV avec Python
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Essayez la touche d'un test basé sur les données avec Selenium Python Bindings et py.test
le zen de Python
Article qui peut être une ressource humaine qui comprend et maîtrise le mécanisme de l'API (avec du code Python)
Extraire le tableau des fichiers image avec OneDrive et Python
L'histoire de Python sans opérateurs d'incrémentation et de décrémentation.
Apprenez Nim avec Python (dès le début de l'année).
Jouez avec l'implémentation de l'interface utilisateur de Pythonista 3 [Super Super Primer]
Le processus d'installation d'Atom et de l'exécution de Python
Détruire l'expression intermédiaire de la méthode sweep avec Python
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
Téléchargez facilement et partiellement mp4 avec python et youtube-dl!
Calculer le coefficient de régression d'une analyse de régression simple avec python
Référence et modification de la limite supérieure récursive Python
J'ai vérifié les versions de Blender et Python
Résumé du flux de base de l'apprentissage automatique avec Python
Obtenez l'état de fonctionnement de JR West avec Python
Comparaison de CoffeeScript avec la grammaire JavaScript, Python et Ruby
Gestion des versions de Node, Ruby et Python avec anyenv
Construisez un serveur API pour vérifier le fonctionnement de l'implémentation frontale avec python3 et Flask
Extraire des images et des tableaux de pdf avec python pour réduire la charge de reporting
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
J'ai essayé de trouver l'entropie de l'image avec python
Essayez de gratter les données COVID-19 Tokyo avec Python
Chiffrement et déchiffrement avec Python
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
Mécanisme de pyenv et virtualenv
Vers la retraite de Python2
Python et matériel - Utilisation de RS232C avec Python -
L'histoire de la mise en œuvre du sujet Facebook Messenger Bot avec python