Verify webhook signature

Hi, i’m getting stuck verifying the webhook signature sent with the identity events.
I’m able to do this in Python, but not in Javascript.
Here is the JS code :

function validateJsonWebhook(request) {
    try {
        var decoded = jwt.decode(request.headers["x-webhook-signature"]);
        var signature = decoded.sha256;
        console.log(WEBHOOK_SECRET);
        var computed = crypto.createHmac('sha256', WEBHOOK_SECRET).update(JSON.stringify(request.body), 'utf-8').digest('hex');
        console.log("Signature: ", signature, "Computed: ", computed);
        if (signature !== computed) {
            return false;
        }else{
            return true;
        }
    } catch(err) {
        console.log(err);
        return false;
    }
}

Thanks for the help !

Hi @Zane,

Could you let us know the use case? What web hook signature are we talking about here?

Hi @hrishikesh ,
The ‘x-webhook-signature’ from identity event trigger

Hey there! Thanks for your patience.

We may be confusing Identity-driven functions and deploy notifications.

Is there any chance you can share your working Python code? This will help us to understand what you’re trying to achieve!

Hi!
Here is the working python code:

data = json.loads(request.data)
decoded = jwt.decode(
            request.headers['X-Webhook-Signature'], WEBHOOK_SECRET, algorithms=["HS256"])
payload_hash = hashlib.sha256(request.data).hexdigest()
if decoded['sha256'] == payload_hash:
    # doing stuff

Hi @Zane,

Could you confirm if this is the case?

I never used Deploy notifications, it’s all about identity

So, the JS that you’re running is inside a serverless function possibly triggered by one of the identity events?

We’re asking this so that we know what you’re trying to do and reproduce the error accordingly. Then we could provide you some solution or workaround.

The JS function is inside an API route hosted on Heroku. The events trigering this route are login and signup from identity.
I’m trying to be sure that the route is called by netlify.

I’m still having troubles to wrap my head around what you’re trying.

When you say the events triggered by Identity, you mean the serverless functions, I suppose? So, you’re calling the Heroku app from within the function and passing the event data to it? Is that correct?

It would also help if you could share a repo in which you’re trying this or point to docs you’re referring to.

@Zane,

I think I’ve understood what you’re trying. I’ll test it myself and let you know the solution.

I’m running a React app on Netlify, powered by identity. When a user logs in or sign up, the identity webhook is triggered (pointing to my api route hosted on heroku) and I can perform custom backend stuff.
From the API I want to make sure that the data received comes from netlify (using the webhook secret known only by me and netlify)

Thank you for the description. I’ll get this checked and revert asap.

1 Like

Just to confirm WEBHOOK_SECRET is your hardcoded secret that you’ve added in Netlify UI, correct?

If that’s the case, I don’t think you need to do it this way. You can simply use:

jwt.verify(event.headers['x-webhook-signature'], 'WEBHOOK_SECRET') and it will decode successfully only if the secret you add here === the secret you set in Netlify UI.

So, you could do something like:

try {
  jwt.verify(request['x-webhook-signature'], 'WEBHOOK_SECRET')
  console.log('This will log only when it decoded successfully')
} catch(error) {
  // It failed because the correct secret could not decode the 'wrong' signature
  console.log(error)
}
1 Like