Github推送事件签名不匹配

mar*_*lhc 35 javascript github webhooks github-api

我正在为GitHub编写一个Webhook,并在以下位置实现安全验证KOA.js:

function sign(tok, blob) {
  var hmac;

  hmac = crypto
    .createHmac('sha1', tok)
    .update(blob)
    .digest('hex');

  return 'sha1=' + hmac;
}

...

key = this.request.headers['x-hub-signature'];
blob = JSON.stringify(this.request.body);

if (!key || !blob) {
  this.status = 400;
  this.body = 'Bad Request';
}

lock = sign(settings.api_secret, blob);

if (lock !== key) {
  console.log(symbols.warning, 'Unauthorized');
  this.status = 403;
  this.body = 'Unauthorized';
  return;
}

...
Run Code Online (Sandbox Code Playgroud)

对于pull_requests和create事件,这工作正常,即使推送新分支也可以工作,但是对于推送提交事件,x-hub-signature来自有效负载的计算哈希值不匹配,因此它总是获得403未授权.

更新

我注意到,对于这种推送有效载荷,提交和head_commit被添加到有效载荷中.我已经尝试从正文中删除提交和head_commit但它没有用.

更新

有关更多信息,请查看这些示例有效负载.我还为测试回购和令牌信息添加了url:https://gist.github.com/marcoslhc/ec581f1a5ccdd80f8b33

jav*_*ett 11

Crypto hash.update()默认编码是二进制文件,详见Node JS加密文件的答案,无法在带重音符号的字符上创建hmac.这会导致你的推事件负载,它包含字符的问题U+00E1 拉丁小写字母A和急性Hernández四倍,而GitHub的服务是散列法的有效载荷utf-8进行编码.请注意,您的Gist在ISO-8859-1中显示了这些错误编码,因此还要确保正确处理传入请求字符编码(但这应该默认情况下发生).

要解决此问题,您需要使用Buffer:

hmac = crypto.createHmac('sha1', tok).update(new Buffer(blob, 'utf-8')).digest('hex');
Run Code Online (Sandbox Code Playgroud)

...或直接将编码传递给update:

hmac = crypto.createHmac('sha1', tok).update(blob, 'utf-8').digest('hex');
Run Code Online (Sandbox Code Playgroud)

7f9e6014b7bddf5533494eff6a2c71c4ec7c042d然后将计算正确的哈希值.