HMAC for webhooks can be calculated using SHA256 and SHA512 algorithms combined with the data and the key. You can also use MD5, SHA1 but those methods are no longer recommended.
It may be used to simultaneously verify both the data integrity and the authenticity of a message. In this example we will use GitHub webhooks. Other providers that use HMAC authentication:
While this example is using GitHub, the same approach can be used for other providers. You will only need to modify two lines of the function when using other providers:
local signature_header = 'X-Hub-Signature-256'will need to include your provider’s header name
if "sha256=" .. calculated_hmac ~= r.RequestHeader[signature_header] thenyou might need to change the prefix
sha256=to something else or remove it completely based on your provider docs
Go to the Functions page and create a new Function with the given code:
local crypto = require('crypto') -- Header name that contains HMAC signature local signature_header = 'X-Hub-Signature-256' -- Calculate HMAC of the request body using SHA256 local calculated_hmac, err = crypto.hmac( 'sha256', r.RequestBody, cfg:GetValue("WEBHOOK_SECRET")) if err then error(err) end -- Check whether calculated HMAC matches the one that was sent -- with the message. Adding the prefix "sha256=" as our signature -- that is coming from GitHub will have it. if "sha256=" .. calculated_hmac ~= r.RequestHeader[signature_header] then r:SetResponseStatusCode(401) r:SetResponseBody("Authentication failure: " .. calculated_hmac) r:StopForwarding() return end r:SetResponseBody("OK")
Once created, click on “config variables” and add the
WEBHOOK_SECRET which is used to sign the webhook requests:
and then enter the same secret in the webhook provider. For this example I will be using GitHub:
Once webhook is added, GitHub will send a test payload.
Testing HMAC verification
You can take the payload from GitHub events page and copy paste it into the Function composer together with the
Testing HMAC failure case
HMAC works by computed hash of the body and the secret key. If you edit the request body by just adding some letters and retry, HMAC verification will fail: