From dfa4359f2334b791a22b8606c381181a0314fcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 3 Mar 2018 02:31:54 +0100 Subject: [PATCH] =?UTF-8?q?Add=20Gogs=20signature=20check=20=E2=80=94=20un?= =?UTF-8?q?tested?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gogsmaker.py | 19 ++++++++++++++++--- settings.default.py | 8 ++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gogsmaker.py b/gogsmaker.py index 78e8b53..9375167 100644 --- a/gogsmaker.py +++ b/gogsmaker.py @@ -5,6 +5,8 @@ A webhook-handler for Gogs running `make` when needed. """ import os import sys import subprocess +import hmac +from hashlib import sha256 from threading import Thread from functools import wraps from flask import Flask, request @@ -77,13 +79,18 @@ def update_repo(hook, clone_url): raise GitError("Cannot clone {}".format(clone_url)) +def check_signature(received_sig, hook, payload): + ''' Check Gogs signature ''' + digest = hmac.new(hook.secret, + msg=payload, + digestmod=sha256).digest() + return hmac.compare_digest(digest, received_sig) + + def gogs_payload(required): def wrapper(fct): @wraps(fct) def wrapped(*args, **kwargs): - # TODO: check signature - # payload_raw = request.data - payload = request.json if payload is None: return 'Expected json\n', 415 @@ -104,6 +111,12 @@ def gogs_payload(required): except UnmonitoredRepository: return 'Unmonitored repository\n', 403 + if not settings.DEBUG: + received_sig = request.headers['X-Gogs-Signature'] + payload_raw = request.data + if not check_signature(received_sig, hook, payload_raw): + return 'Invaild signature\n', 403 + return fct(payload, hook, *args, **kwargs) return wrapped return wrapper diff --git a/settings.default.py b/settings.default.py index 42f5aa7..7bb903c 100644 --- a/settings.default.py +++ b/settings.default.py @@ -1,5 +1,9 @@ ''' GogsMaker settings ''' +# Debug mode. **ALWAYS** leave to False in production, this allows remote code +# execution +DEBUG = False + # List of the repositories to work on HOOKS = [ { @@ -12,11 +16,15 @@ HOOKS = [ # Make targets to be invoked 'targets': ['all'], + + # Shared secret with Gogs + 'secret': 'shooW8IRei5pah7lahMe', }, { 'name': 'test-repo', 'url': 'tests/simple-repo', 'targets': ['date', 'touch'], + 'secret': 'mi5aesh8eiS6sileiGha', }, ]