mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
refactor: check HTTP signatures on all activitypub requests
- `validate` is now renamed `assertPayload` - HTTP signature checking is now in new middleware `verify` - `verify` is now called on all routes in activitypub controller - Rejects on signature failure for POST requests
This commit is contained in:
@@ -28,7 +28,33 @@ middleware.assertS2S = async function (req, res, next) {
|
||||
next();
|
||||
};
|
||||
|
||||
middleware.validate = async function (req, res, next) {
|
||||
middleware.verify = async function (req, res, next) {
|
||||
// Verifies the HTTP Signature if present (required for POST)
|
||||
const passthrough = [/\/actor/, /\/uid\/\d+/];
|
||||
if (req.method === 'GET' && passthrough.some(regex => regex.test(req.path))) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const verified = await activitypub.verify(req);
|
||||
if (!verified && req.method === 'POST') {
|
||||
// winston.verbose('[middleware/activitypub] HTTP signature verification failed.');
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
// Set calling user
|
||||
if (req.headers.signature) {
|
||||
const keyId = req.headers.signature.split(',').filter(line => line.startsWith('keyId="'));
|
||||
if (keyId.length) {
|
||||
req.uid = keyId.shift().slice(7, -1).replace(/#.*$/, '');
|
||||
}
|
||||
}
|
||||
|
||||
// winston.verbose('[middleware/activitypub] HTTP signature verification passed.');
|
||||
next();
|
||||
};
|
||||
|
||||
middleware.assertPayload = async function (req, res, next) {
|
||||
// Checks the validity of the incoming payload against the sender and rejects on failure
|
||||
// winston.verbose('[middleware/activitypub] Validating incoming payload...');
|
||||
|
||||
// Sanity-check payload schema
|
||||
@@ -46,14 +72,6 @@ middleware.validate = async function (req, res, next) {
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
// Checks the validity of the incoming payload against the sender and rejects on failure
|
||||
const verified = await activitypub.verify(req);
|
||||
if (!verified) {
|
||||
// winston.verbose('[middleware/activitypub] HTTP signature verification failed.');
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
// winston.verbose('[middleware/activitypub] HTTP signature verification passed.');
|
||||
|
||||
let { actor, object } = req.body;
|
||||
|
||||
// Actor normalization
|
||||
|
||||
@@ -14,11 +14,12 @@ module.exports = function (app, middleware, controllers) {
|
||||
const middlewares = [
|
||||
middleware.activitypub.enabled,
|
||||
middleware.activitypub.assertS2S,
|
||||
middleware.activitypub.verify,
|
||||
middleware.activitypub.configureResponse,
|
||||
];
|
||||
|
||||
const inboxMiddlewares = [
|
||||
middleware.activitypub.validate,
|
||||
middleware.activitypub.assertPayload,
|
||||
middleware.activitypub.resolveObjects,
|
||||
];
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('Analytics', () => {
|
||||
},
|
||||
}, { sendStatus: () => {} });
|
||||
|
||||
await middleware.activitypub.validate({
|
||||
await middleware.activitypub.assertPayload({
|
||||
body: {
|
||||
id,
|
||||
type: 'Like',
|
||||
|
||||
Reference in New Issue
Block a user