valid github signature check

This commit is contained in:
Klemek
2019-06-20 20:19:03 +02:00
parent c1c8672380
commit 0f5b3f138d
6 changed files with 45 additions and 16 deletions
+3 -3
View File
@@ -63,14 +63,14 @@ Create a webhook on your git source (On GitHub, in the `Settings/Webhooks` part
Here are the steps for Github, if you use another platform adapt it your way (header format on the config) :
* Create a password or random secret
* Calculate it's SHA1
* Edit your configuration to add webhook info
```json
{
...
"webhook": {
"secret_value": "sha1=<value>",
"secret_header": "X-Hub-Signature"
"endpoint": "/webhook",
"secret": "sha1=<value>",
"signature_header": "X-Hub-Signature"
},
...
}
+5
View File
@@ -2704,6 +2704,11 @@
"which": "^1.2.9"
}
},
"crypto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig=="
},
"cssom": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
+2
View File
@@ -5,6 +5,8 @@
"description": "A static blog using Markdown pulled from your git repository.",
"main": "src/server.js",
"dependencies": {
"body-parser": "^1.19.0",
"crypto": "^1.0.1",
"ejs": "^2.6.2",
"express": "^4.17.1",
"ncp": "^2.0.0",
+16 -5
View File
@@ -3,6 +3,9 @@ const app = express();
const fs = require('fs');
const path = require('path');
const Rss = require('rss');
const bodyParser = require('body-parser');
const crypto = require('crypto');
app.use(bodyParser.json());
/**
* Terminal colors and symbols to display status messages
@@ -127,12 +130,20 @@ module.exports = (config) => {
//webhook endpoint
app.post(config['webhook']['endpoint'], (req, res) => {
if (config['modules']['webhook']) {
if (config['webhook']['secret_header'] && req.get(config['webhook']['secret_header']) !== config['webhook']['secret_value']) {
res.sendStatus(403);
} else {
res.sendStatus(200);
//TODO reload
if (config['webhook']['signature_header'] && config['webhook']['secret']) {
const payload = JSON.stringify(req.body);
if (!payload) {
return res.sendStatus(403);
}
const hmac = crypto.createHmac('sha1', config['webhook']['secret']);
const digest = 'sha1=' + hmac.update(payload).digest('hex');
const checksum = req.headers[config['webhook']['signature_header']];
if (!checksum || !digest || checksum !== digest) {
return res.sendStatus(403);
}
}
res.sendStatus(200);
//TODO reload
} else {
res.sendStatus(400);
}
+2 -2
View File
@@ -30,8 +30,8 @@
},
"webhook": {
"endpoint": "/webhook",
"secret_value": "",
"secret_header": ""
"secret": "",
"signature_header": ""
},
"showdown": {
"parseImgDimensions": true,
+17 -6
View File
@@ -151,18 +151,29 @@ describe('Test webhook', () => {
done();
});
});
test('403 no payload', (done) => {
config['webhook']['signature_header'] = 'testheader';
config['webhook']['secret'] = 'testvalue';
request(app).post('/webhooktest').then((response) => {
expect(response.statusCode).toBe(403);
done();
});
});
test('403 wrong secret', (done) => {
config['webhook']['secret_header'] = 'testheader';
config['webhook']['secret_value'] = 'testvalue';
request(app).post('/webhooktest').set('testheader','testvalue2').then((response) => {
config['webhook']['signature_header'] = 'testheader';
config['webhook']['secret'] = 'testvalue';
request(app).post('/webhooktest').set('testheader', 'sha1=invalid').then((response) => {
expect(response.statusCode).toBe(403);
done();
});
});
test('200 valid secret', (done) => {
config['webhook']['secret_header'] = 'testheader';
config['webhook']['secret_value'] = 'testvalue';
request(app).post('/webhooktest').set('testheader','testvalue').then((response) => {
config['webhook']['signature_header'] = 'testheader';
config['webhook']['secret'] = 'testvalue';
request(app).post('/webhooktest')
.send({})
.set('testheader', 'sha1=d924d5bd4b36faf9d572844ac9c12a09ce3e7134')
.then((response) => {
expect(response.statusCode).toBe(200);
//TODO test reload
done();