2014-09-10 15 views
6

Tôi đang sử dụng một webhook GitHub cho các sự kiện ống đến một ứng dụng của tôi (một thể hiện của Hubot của GitHub) và nó được bảo mật bằng một bí mật sha1.GitHub Webhook Secret Không bao giờ xác nhận

Tôi đang sử dụng đoạn mã sau để xác nhận băm trên webhooks đến

crypto = require('crypto') 
signature = "sha1=" + crypto.createHmac('sha1', process.env.HUBOT_GITHUB_SECRET).update(new Buffer request.body).digest('hex') 
unless request.headers['x-hub-signature'] is signature 
    response.send "Signature not valid" 
    return 

Phần header X-Hub-Chữ ký qua trong webhook trông như thế này

X-Hub-Chữ ký : sha1 = 1cffc5d4c77a3f696ecd9c19dbc2575d22ffebd4

Tôi đang chuyển chính và dữ liệu chính xác theo tài liệu của GitHub, nhưng hàm băm luôn kết thúc s lên khác nhau.

Đây là tài liệu của GitHub. https://developer.github.com/v3/repos/hooks/#example

và đây là phần mà tôi đang rất có thể hiểu sai

bí mật: Một chuỗi không bắt buộc đó là thông qua với các yêu cầu HTTP như một tiêu đề X-Hub-Chữ ký. Giá trị của tiêu đề này được tính như là bản phân tích hex HMAC của cơ thể, sử dụng bí mật làm khóa.

Có ai có thể thấy tôi đang đi đâu không?

Trả lời

8

Dường như không hoạt động với Bộ đệm, nhưng JSON.stringify(); Đây là mã làm việc của tôi:

var 
    hmac, 
    calculatedSignature, 
    payload = req.body; 

hmac = crypto.createHmac('sha1', config.github.secret); 
hmac.update(JSON.stringify(payload)); 
calculatedSignature = 'sha1=' + hmac.digest('hex'); 

if (req.headers['x-hub-signature'] === calculatedSignature) { 
    console.log('all good'); 
} else { 
    console.log('not good'); 
} 
+2

Dường như không hoạt động đối với tôi – ditoslav

+2

Điều quan trọng cần lưu ý là hookit GitHub * phải * có Content-Type được đặt thành 'application/json'. Bạn sẽ tìm thấy các cài đặt này trên trang cấu hình webhook. https://github.com/MY_ORG/MY_REPO/settings/hooks/HOOK_ID#delivery-response –

+0

Giống như trạng thái @MrClean, hãy sử dụng ứng dụng/json! – Mattis

1

Thêm vào câu trả lời Patrick's. Bạn nên sử dụng crypo.timingSafeEqual để so sánh các tiêu chuẩn hoặc giá trị bí mật của HMAC. Đây là cách:

const blob = JSON.stringify(req.body); 
const hmac = crypto.createHmac('sha1', process.env.GITHUB_WEBHOOK_SECRET); 
const ourSignature = `sha1=${hmac.update(blob).digest('hex')}`; 

const theirSignature = req.get('X-Hub-Signature'); 

const bufferA = Buffer.from(ourSignature, 'utf8'); 
const bufferB = Buffer.from(theirSignature, 'utf8'); 

const safe = crypto.timingSafeEqual(bufferA, bufferB); 

if (safe) { 
    console.log('Valid signature'); 
} else { 
    console.log('Invalid signature'); 
} 

Để biết thêm về sự khác biệt giữa một an toàn so sánh như timingEqual và đơn giản === kiểm tra chủ đề này here.

crypto.timingSafeEqual đã được bổ sung trong Node.js v6.6.0

2

Cũng thêm vào câu trả lời Patrick, tôi khuyên bạn nên sử dụng tốc cùng với đó là cơ thể phân tích cú pháp. Ví dụ hoàn chỉnh bên dưới. Điều này làm việc với Express 4.x, Node 8.x (mới nhất bằng văn bản).

Vui lòng thay thế YOUR_WEBHOOK_SECRET_HERE và làm điều gì đó trong chức năng authorizationSuccessful.

// Imports 
const express = require('express'); 
const bodyParser = require('body-parser'); 
const crypto = require('crypto'); 

const app = express(); 
// The GitHub webhook MUST be configured to be sent as "application/json" 
app.use(bodyParser.json()); 

// Verification function to check if it is actually GitHub who is POSTing here 
const verifyGitHub = (req) => { 
    if (!req.headers['user-agent'].includes('GitHub-Hookshot')) { 
    return false; 
    } 
    // Compare their hmac signature to our hmac signature 
    // (hmac = hash-based message authentication code) 
    const theirSignature = req.headers['x-hub-signature']; 
    const payload = JSON.stringify(req.body); 
    const secret = 'YOUR_WEBHOOK_SECRET_HERE'; // TODO: Replace me 
    const ourSignature = `sha1=${crypto.createHmac('sha1', secret).update(payload).digest('hex')}`; 
    return crypto.timingSafeEqual(Buffer.from(theirSignature), Buffer.from(ourSignature)); 
}; 

const notAuthorized = (req, res) => { 
    console.log('Someone who is NOT GitHub is calling, redirect them'); 
    res.redirect(301, '/'); // Redirect to domain root 
}; 

const authorizationSuccessful =() => { 
    console.log('GitHub is calling, do something here'); 
    // TODO: Do something here 
}; 

app.post('*', (req, res) => { 
    if (verifyGitHub(req)) { 
    // GitHub calling 
    authorizationSuccessful(); 
    res.writeHead(200, { 'Content-Type': 'text/plain' }); 
    res.end('Thanks GitHub <3'); 
    } else { 
    // Someone else calling 
    notAuthorized(req, res); 
    } 
}); 

app.all('*', notAuthorized); // Only webhook requests allowed at this address 

app.listen(3000); 

console.log('Webhook service running at http://localhost:3000'); 
+0

Lưu ý: Sửa lỗi trong đó 'req.body' được xâu chuỗi hai lần. –

Các vấn đề liên quan