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) :
|
||||
|
||||
* 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"
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
Generated
+5
@@ -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",
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"webhook": {
|
||||
"endpoint": "/webhook",
|
||||
"secret_value": "",
|
||||
"secret_header": ""
|
||||
"secret": "",
|
||||
"signature_header": ""
|
||||
},
|
||||
"showdown": {
|
||||
"parseImgDimensions": true,
|
||||
|
||||
+17
-6
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user