0

I am trying to validate GitHub webhook secret using API Gateway.

This is my lambda:

import json
import hmac
import hashlib
import re


GITHUB_SECRET = 'HELLO WORLD' # from Github UI


def lambda_handler(event, context):
    print("Lambda execution starting up...")

    incoming_signature = re.sub(r'^sha1=', '', event['headers']['X-Hub-Signature'])
    enhanced_body_msg = json.dumps(event['body'], default=str)
    calculated_signature = calculate_signature(GITHUB_SECRET, enhanced_body_msg.encode('utf-8'))

    print("Incoming sig:", incoming_signature)
    print("calculated_signature:", calculated_signature)
    if incoming_signature != calculated_signature:
        print('Unauthorized attempt')
        return {
            'statusCode': 403,
            'body': json.dumps('Forbidden')
        }

    print('Request successfully authorized')

    # do stuff in Lambda

    return {
        'statusCode': 200,
        'body': json.dumps(f'Work in progress')
    }


def calculate_signature(github_signature, githhub_payload):
    signature_bytes = bytes(github_signature, 'utf-8')
    digest = hmac.new(key=signature_bytes, msg=githhub_payload, digestmod=hashlib.sha1)
    signature = digest.hexdigest()
    return signature

Used this as a reference(Github Webhooks secret with AWS API Gateway) but still, it's always failing to match. Please if someone can point out a mistake. Also tried for X-Hub-Signature-256 same issue.

tomarv2
  • 753
  • 3
  • 14
  • Are you using Lambda Integration or Proxy lambda integration? – lynkfox Oct 06 '21 at 23:48
  • Integration type: Lambda Function – tomarv2 Oct 06 '21 at 23:54
  • So i always forget which does which, but Integration: Lambda with or without the proxy lambad box checked changes the body of the event being passed in. I would do a quick test with a print(event[body]) in your code to see what it looks like. Quite likely what you * think* is the github body is not yet, and that is actually a few more levels deep. Or, if you've already verified that, then throw in some more print statements! find out what each value is coming out as, but i suspect the next problem is the wrong haslib but ... thats outside my knowledge base. – lynkfox Oct 07 '21 at 00:01
  • @lynkfox checking proxy lambda box worked, adding answer in case someone else gets stuck. Thanks for the suggestion. – tomarv2 Oct 07 '21 at 00:39

1 Answers1

1

Working Lambda function with sha256:

import hmac
import hashlib
import re


GITHUB_SECRET = 'hello' # from Github UI

def calculate_signature(github_signature, payload):
    """
    Signature calculator
    """
    signature_bytes = bytes(github_signature, 'utf-8')
    digest = hmac.new(key=signature_bytes, msg=payload, digestmod=hashlib.sha256)
    signature = digest.hexdigest()
    print(f"Calculated signature: {signature}")
    return signature
    
def lambda_handler(event, context):
    print("Lambda execution starting...")
    incoming_signature = re.sub(r'^sha256=', '', event['headers']['X-Hub-Signature-256'])
    print(f"Incoming Signature: {incoming_signature}")
    calculated_signature = calculate_signature(GITHUB_SECRET, event['body'].encode('utf-8'))
    if incoming_signature != calculated_signature:
        print("Unauthorized attempt")
    else:
        print("Authorized access")
    # Lambda logic 


In API Gateway configuration, ensure `Lambda Proxy Integration` box should is checked, else the body from github is not what is needed.
tomarv2
  • 753
  • 3
  • 14