验证 Github Webhook HMAC 签名 Lucee Coldfusion 和 CFWheels

Validate Github Webhook HMAC Signature Lucee Coldfusion and CFWheels

我正在尝试从 github 验证我的 webhook 的签名。在their documentation之后,只有ruby的例子:

post '/payload' do
  request.body.rewind
  payload_body = request.body.read
  verify_signature(payload_body)
  push = JSON.parse(payload_body)
  "I got some JSON: #{push.inspect}"
end

def verify_signature(payload_body)
  signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ENV['SECRET_TOKEN'], payload_body)
  return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE_256'])
end

Lucee here 有一个内置的 hmac 函数,按照一些 ruby 示例,我已经能够为像“the fox”这样的简单消息重新创建相同的散列跳过那个东西。”但是,一旦我尝试使用请求有效负载重新创建签名,我就永远无法获得正确的签名。我已经三次检查了我的秘密,它与 webhook 中使用的秘密一致,所以我很确定问题出在我解析有效负载的方式上。以下是我当前的代码:

headers = request.wheels.HTTPREQUESTDATA.headers;
signature = structKeyExists(headers, "X-Hub-Signature-256") ? headers["X-Hub-Signature-256"] : "error";
payload = request.wheels.params.payload;
mac = 'sha256=' & lCase(hmac(payload, secret, "HMACSHA256"));

这导致两个不同的“sha256=...”字符串。我的负载字符串(似乎是正确的格式):

{"action":"added_to_repository",...

如有任何建议,我们将不胜感激。

我刚刚创建了一个测试 Github webhook,并且能够使用以下基本代码在 Lucee 中成功验证推送事件:

boolean function verifySignature( required string signature, required string payload, required string secret ){
 var expectedSignature = "sha256=" & HMAC( arguments.payload, arguments.secret, "HmacSHA256", "utf-8" ).LCase()
 return ( arguments.signature == expectedSignature )
}

requestData = GetHTTPRequestData()
payload = requestData.content.Trim()
signature = requestData.headers[ "X-Hub-Signature-256" ]
secret = "mysecret"
result.verified = verifySignature( signature, payload, secret )
dump( result )

与您的一些小差异:

  • 我直接使用 GetHTTPRequestData() built-in 函数而不是 CFWheels-provided 值
  • 我已经修剪了负载
  • 我已将 utf-8 指定为 HMAC() 函数的字符编码