[GO] Spielen Sie mit dem Passwortmechanismus von GitHub Webhook und Python

secret.png

Was freut dieses geheime Feld (゜ ∀ ゜)

Ich habe kürzlich das Gefühl, dass dies eingegeben wurde. Ich werde den Prozess aufschreiben, den ich grob versucht habe. Bitte weisen Sie auf Fehler hin.

Was für eine Funktion

Kurz gesagt, GitHub sendet Ihnen die Signatur der Nutzdaten.

Das Ergebnis der Anwendung der JSON-Nutzdaten, die mit diesem Schlüssel an HMAC (Keyed Hash) gesendet werden sollen Es ist ein Mechanismus, der in den HTTP-Header von WebHook eingefügt wird. Das Geheimnis wird nach der Eingabe nicht auf dem GitHub-Bildschirm angezeigt und erscheint danach in den HTTP-Daten nicht mehr roh, so dass dies auch ein wenig sicher ist.

Sie können erneut eingeben

Ich denke, dieser Mechanismus gab es in der Vergangenheit nicht. Wahrscheinlich nicht direkt nach der Erneuerung des WebHook. Wann bist du reingekommen?

Referenz: http://blog.manaten.net/entry/573

Wenn ich mir die obige Seite anschaue, spüre ich die Bedeutung der Aufbewahrung von Informationen. Es gibt kein Passwortfeld, ich habe es selbst in die Abfragezeichenfolge eingefügt. Es war vor einem Jahr.

Was mich glücklich macht

Sie können das Sicherheitsniveau leicht erhöhen.

Sie können grundsätzlich POST an die WebHook-URL senden und keine CSRF-Token einbetten. Jedes Mal, wenn ich in Django `` @ csrf_exempt``` schreibe, sinkt der SAN-Wert, aber es kann nicht geholfen werden.

Derzeit scheint WebHooks Mund in der Lage zu sein, IP-Beschränkungen lose anzuwenden, daher werde ich sie verwenden. Dennoch gibt es Bedenken, dass etwas aus dem bösartigen GitHub-Projekt kommen könnte. Es scheint, dass alle oder eine beträchtliche Menge der gesendeten Informationen getarnt werden können (obwohl ich sie nicht untersucht habe).

Also wollte ich eigentlich einen anderen Schlüssel als die URL. Aber ich möchte die Implementierung nicht selbst schreiben (die Leute auf der obigen Seite schreiben sie selbst, nicht wahr?)

Was für ein Verhalten

Wenn GitHub einen WebHook sendet, konvertiert es die Zeichenfolge in seiner JSON-Nutzlast mit HMAC + sha1 unter Verwendung des Schlüssels in einen 40-stelligen Hash. Wenn Sie also einen HTTP-POST senden, wird eine Zeichenfolge wie `` `sha1 = dd671d65f5aee8c8aba748fd8f0143c10c5ba875``` in den Header eingefügt. Der Server (Sie selbst) erhält die Nutzdaten und ihre "Signatur".

Der Empfänger oder Ihr eigener Server kann die Signatur überprüfen, indem er die mit dem gemeinsamen Schlüssel gesendete JSON-Zeichenfolge in einen Hash mit demselben Algorithmus konvertiert. Wenn die Signatur falsch ist, können Sie eine Warnung an den Administrator senden, da dies in Ordnung ist.

Vielleicht ist es nicht allzu schwierig, wenn es sich um eine Skriptsprache mit einem OpenSSL-Wrapper handelt, und da die Algorithmen selbst für HMAC und sha1 normal sind, können Sie sie wahrscheinlich mit der Shell überprüfen (was bedeutet, dass Sie kein "sha1sum" verwenden. Ich werde es nicht versuchen, ich werde es nie versuchen).

Es scheint, dass die Bibliothek genauso verwendet wird wie in der (anscheinend) Ruby-Implementierung, die von GitHub selbst verwendet wird.

Es ist auch in Python. Ein bewusster Python-Geschmack.

Verwenden wir es mit Python (+ Django)

Um die JSON-Nutzdaten zu empfangen, bereiten Sie zwei Arten von Untertassen entsprechend dem Inhaltstyp auf der Serverseite vor. Dies an sich ist unabhängig von dieser Geschichte etwas zu implementieren.

Außerdem wird die gesendete Zeichenfolge über "request.META.get (" HTTP_X_HUB_SIGNATURE ") abgerufen.

Wenn es leer ist, gibt es kein Passwort. Wenn es nicht leer ist, fügen Sie die unformatierte Nutzlastzeichenfolge in hmac / hashlib.sha1 ein und generieren Sie selbst einen verschlüsselten Hash, um festzustellen, ob er identisch ist.

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()))

Ich finde das gut, weil die Berechnungsergebnisse korrekt sind.

Ich bin mir jedoch nicht sicher, ob die Codierung und der Zeilenvorschubcode jedes Mal übereinstimmen. Wenn Sie Details haben, kommentieren Sie bitte.

Bonus

Ich möchte mich nicht an den Rohschlüssel auf der Serverseite erinnern, aber wenn Sie einen einfachen und guten Weg kennen, lassen Sie es mich bitte wissen. Ich frage mich, ob es einfach ist, die mit Django serialisierten zu speichern ...

Nachtrag: Beim Testen mit django.test.Client

Wenn die Nutzlast selbst als Zeichenfolge bereit ist, müssen Sie nur das oben generierte Ergebnis in das Header-Äquivalent schrauben. In Django 1.6.5 kann es wie folgt integriert werden.

        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()))

Es ist Django 1.6.5, aber wenn Sie "application / x-www-form-urlencoded" festlegen, das auf GitHub als content_type to Client ausgewählt werden kann, können Sie keine POST-Daten mit response.POST.get ('...') empfangen. Es scheint ein Problem zu geben. Über content_type Ermöglichen wir den Empfang von mehrteiligen / Formulardaten auch auf der Serverseite. GitHub kann sich bald sehr ändern.

Recommended Posts

Spielen Sie mit dem Passwortmechanismus von GitHub Webhook und Python
Visualisieren Sie den Bereich der internen und externen Einfügungen mit Python
Lassen Sie uns mit Python Receive spielen und den Text des Eingabeformulars speichern / anzeigen
Die Geschichte von Python und die Geschichte von NaN
Koexistenz von Python2 und 3 mit CircleCI (1.0)
Ich habe die Geschwindigkeit von Hash mit Topaz, Ruby und Python verglichen
[Erforderliches Thema DI] Implementieren und verstehen Sie den Mechanismus von DI mit Go
Überprüfen Sie die Existenz der Datei mit Python
Spielen Sie mit 2016-Python
Ich habe die numerische Berechnung von Python durch Rust ersetzt und die Geschwindigkeit verglichen
Berechnen Sie die kürzeste Route eines Diagramms mit der Dyxtra-Methode und Python
Holen Sie sich Artikelbesuche und Likes mit Qiita API + Python
Erhalten und schätzen Sie die Form des Kopfes mit Dlib und OpenCV mit Python
Ich habe die Geschwindigkeit der Listeneinschlussnotation für und während mit Python2.7 gemessen.
Bereiten Sie die Ausführungsumgebung von Python3 mit Docker vor
Zusammenfassung der Unterschiede zwischen PHP und Python
2016 Todai Mathematik mit Python gelöst
[Hinweis] Exportieren Sie das HTML der Site mit Python.
Die Antwort von "1/2" unterscheidet sich zwischen Python2 und 3
Berechnen Sie die Gesamtzahl der Kombinationen mit Python
Angeben des Bereichs von Ruby- und Python-Arrays
Vergleichen Sie die Geschwindigkeit von Python Append und Map
TRIE-Baumimplementierung mit Python und LOUDS
Lösen des Lorenz 96-Modells mit Julia und Python
Archivieren und komprimieren Sie das gesamte Verzeichnis mit Python
Konvertieren Sie den Zeichencode der Datei mit Python3
Berücksichtigung der Stärken und Schwächen von Python
[Python] Bestimmen Sie den Typ der Iris mit SVM
Beispiel für das Lesen und Schreiben von CSV mit Python
Deep Learning von Grund auf neu Die Theorie und Implementierung des mit Python erlernten Deep Learning Kapitel 3
Probieren Sie einen datengesteuerten Test mit Selenium Python Bindings und py.test aus
der Zen von Python
Artikel, der eine Person sein kann, die den Mechanismus der API versteht und beherrscht (mit Python-Code)
Extrahieren Sie die Tabelle der Bilddateien mit OneDrive & Python
Die Geschichte von Python ohne Inkrement- und Dekrementoperatoren.
Lerne Nim mit Python (ab Anfang des Jahres).
Spielen Sie mit der Implementierung der Pythonista 3-Benutzeroberfläche [Super Super Primer]
Der Prozess der Installation von Atom und der Ausführung von Python
Zerstören Sie den Zwischenausdruck der Sweep-Methode mit Python
Python - Erläuterung und Zusammenfassung der Verwendung der 24 wichtigsten Pakete
Laden Sie mp4 einfach teilweise mit Python und youtube-dl herunter!
Berechnen Sie den Regressionskoeffizienten der einfachen Regressionsanalyse mit Python
Referenz und Änderung der rekursiven Python-Obergrenze
Ich habe mir die Versionen von Blender und Python angesehen
Zusammenfassung des grundlegenden Ablaufs des maschinellen Lernens mit Python
Holen Sie sich mit Python den Betriebsstatus von JR West
Vergleich von CoffeeScript mit JavaScript-, Python- und Ruby-Grammatik
Versionsverwaltung von Node, Ruby und Python mit anyenv
Erstellen Sie einen API-Server, um den Betrieb der Front-Implementierung mit Python3 und Flask zu überprüfen
Extrahieren Sie Bilder und Tabellen mit Python aus PDF, um die Berichtslast zu verringern
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit dplyr von R und pandas von Python zu vergleichen
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Versuchen Sie, COVID-19 Tokyo-Daten mit Python zu kratzen
Ver- und Entschlüsselung mit Python
Ich habe versucht, das Bild mit Python + OpenCV "gammakorrektur" zu machen
Mechanismus von Pyenv und Virtualenv
Auf dem Weg zum Ruhestand von Python2
Python und Hardware-Verwenden von RS232C mit Python-
Die Geschichte der Implementierung des Themas Facebook Messenger Bot mit Python