From 5d615bd7333313a9c4f94ab2a330653e01237a54 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 12 Feb 2024 10:19:53 +0100 Subject: [PATCH] [IMP] runbot_merge: logging around webhook body & signature The signature validation code seems correct, but there are validation failure in production, increase logging around webhook requests to try and diagnose things better: - dump the *entire* body to the github_requests logfile - add the received & computed signatures to the log error --- runbot_merge/controllers/__init__.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/runbot_merge/controllers/__init__.py b/runbot_merge/controllers/__init__.py index 535591f1..04b7f8c6 100644 --- a/runbot_merge/controllers/__init__.py +++ b/runbot_merge/controllers/__init__.py @@ -96,28 +96,33 @@ class MergebotController(Controller): secret = env['runbot_merge.repository'].search([ ('name', '=', repo), - ]).project_id.secret + ]).project_id.secret.strip() if secret: signature = 'sha256=' + hmac.new(secret.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", - req.headers.get('X-Github-Delivery')) + _logger.warning( + "Ignored hook %s with incorrect signature: got %s expected %s", + req.headers.get('X-Github-Delivery'), + req.headers.get('X-Hub-Signature-256'), + signature, + ) return werkzeug.exceptions.Forbidden() sentry_sdk.set_context('webhook', request.jsonrequest) return c(env, request.jsonrequest) def _format(self, request): - return """<= {r.method} {r.full_path} + return """{r.method} {r.full_path} {headers} + {body} -vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\ """.format( r=request, headers='\n'.join( '\t%s: %s' % entry for entry in request.headers.items() ), - body=utils.shorten(request.get_data(as_text=True).strip(), 400) + body=request.get_data(as_text=True), ) def handle_pr(env, event):