valid github signature check
This commit is contained in:
@@ -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) :
|
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
|
* Create a password or random secret
|
||||||
* Calculate it's SHA1
|
|
||||||
* Edit your configuration to add webhook info
|
* Edit your configuration to add webhook info
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
"webhook": {
|
"webhook": {
|
||||||
"secret_value": "sha1=<value>",
|
"endpoint": "/webhook",
|
||||||
"secret_header": "X-Hub-Signature"
|
"secret": "sha1=<value>",
|
||||||
|
"signature_header": "X-Hub-Signature"
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+5
@@ -2704,6 +2704,11 @@
|
|||||||
"which": "^1.2.9"
|
"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": {
|
"cssom": {
|
||||||
"version": "0.3.6",
|
"version": "0.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
"description": "A static blog using Markdown pulled from your git repository.",
|
"description": "A static blog using Markdown pulled from your git repository.",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"ejs": "^2.6.2",
|
"ejs": "^2.6.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
|
|||||||
+16
-5
@@ -3,6 +3,9 @@ const app = express();
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const Rss = require('rss');
|
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
|
* Terminal colors and symbols to display status messages
|
||||||
@@ -127,12 +130,20 @@ module.exports = (config) => {
|
|||||||
//webhook endpoint
|
//webhook endpoint
|
||||||
app.post(config['webhook']['endpoint'], (req, res) => {
|
app.post(config['webhook']['endpoint'], (req, res) => {
|
||||||
if (config['modules']['webhook']) {
|
if (config['modules']['webhook']) {
|
||||||
if (config['webhook']['secret_header'] && req.get(config['webhook']['secret_header']) !== config['webhook']['secret_value']) {
|
if (config['webhook']['signature_header'] && config['webhook']['secret']) {
|
||||||
res.sendStatus(403);
|
const payload = JSON.stringify(req.body);
|
||||||
} else {
|
if (!payload) {
|
||||||
res.sendStatus(200);
|
return res.sendStatus(403);
|
||||||
//TODO reload
|
}
|
||||||
|
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 {
|
} else {
|
||||||
res.sendStatus(400);
|
res.sendStatus(400);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
"endpoint": "/webhook",
|
"endpoint": "/webhook",
|
||||||
"secret_value": "",
|
"secret": "",
|
||||||
"secret_header": ""
|
"signature_header": ""
|
||||||
},
|
},
|
||||||
"showdown": {
|
"showdown": {
|
||||||
"parseImgDimensions": true,
|
"parseImgDimensions": true,
|
||||||
|
|||||||
+17
-6
@@ -151,18 +151,29 @@ describe('Test webhook', () => {
|
|||||||
done();
|
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) => {
|
test('403 wrong secret', (done) => {
|
||||||
config['webhook']['secret_header'] = 'testheader';
|
config['webhook']['signature_header'] = 'testheader';
|
||||||
config['webhook']['secret_value'] = 'testvalue';
|
config['webhook']['secret'] = 'testvalue';
|
||||||
request(app).post('/webhooktest').set('testheader','testvalue2').then((response) => {
|
request(app).post('/webhooktest').set('testheader', 'sha1=invalid').then((response) => {
|
||||||
expect(response.statusCode).toBe(403);
|
expect(response.statusCode).toBe(403);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('200 valid secret', (done) => {
|
test('200 valid secret', (done) => {
|
||||||
config['webhook']['secret_header'] = 'testheader';
|
config['webhook']['signature_header'] = 'testheader';
|
||||||
config['webhook']['secret_value'] = 'testvalue';
|
config['webhook']['secret'] = 'testvalue';
|
||||||
request(app).post('/webhooktest').set('testheader','testvalue').then((response) => {
|
request(app).post('/webhooktest')
|
||||||
|
.send({})
|
||||||
|
.set('testheader', 'sha1=d924d5bd4b36faf9d572844ac9c12a09ce3e7134')
|
||||||
|
.then((response) => {
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200);
|
||||||
//TODO test reload
|
//TODO test reload
|
||||||
done();
|
done();
|
||||||
|
|||||||
Reference in New Issue
Block a user