From 721b76903909149bbceeef95150d8ca9a91f6ca6 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 26 Feb 2024 10:11:53 +0100 Subject: [PATCH] [IMP] runbot_merge: handling of signatures - correctly handle projects without a secret set, we don't want the requests to blow up by trying to `strip()` a `False` or `None`, that is dumb, who would do that? - provide better reporting on signature mismatch: which repo we tried to access, and the full list of headers - log when there was no signature matching, either because there was no signature in the request and no secret on the project, or because the request is signed but no secret is configured on the repo --- runbot_merge/controllers/__init__.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/runbot_merge/controllers/__init__.py b/runbot_merge/controllers/__init__.py index 04b7f8c6..35c4e542 100644 --- a/runbot_merge/controllers/__init__.py +++ b/runbot_merge/controllers/__init__.py @@ -96,17 +96,23 @@ class MergebotController(Controller): secret = env['runbot_merge.repository'].search([ ('name', '=', repo), - ]).project_id.secret.strip() - if secret: - signature = 'sha256=' + hmac.new(secret.encode(), req.get_data(), hashlib.sha256).hexdigest() + ]).project_id.secret + if secret and secret.strip(): + signature = 'sha256=' + hmac.new(secret.strip().encode(), req.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(signature, req.headers.get('X-Hub-Signature-256', '')): _logger.warning( - "Ignored hook %s with incorrect signature: got %s expected %s", + "Ignored hook %s with incorrect signature on %s: got %s expected %s, in:\n%s", req.headers.get('X-Github-Delivery'), + repo, req.headers.get('X-Hub-Signature-256'), signature, + req.headers, ) return werkzeug.exceptions.Forbidden() + elif req.headers.get('X-Hub-Signature-256'): + _logger.info("No secret for %s but received a signature in:\n%s", repo, req.headers) + else: + _logger.info("No secret or signature for %s", repo) sentry_sdk.set_context('webhook', request.jsonrequest) return c(env, request.jsonrequest)