Skip to content

Commit

Permalink
validate signed headers
Browse files Browse the repository at this point in the history
* validate signed headers

* リクエストホスト

Co-authored-by: perillamint <[email protected]>
Co-authored-by: yunochi <[email protected]>
Co-authored-by: Laura Hausmann <[email protected]>
  • Loading branch information
4 people committed Dec 2, 2023
1 parent a97e3a3 commit 5317d27
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 38 deletions.
3 changes: 2 additions & 1 deletion packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"chalk-template": "0.4.0",
"chokidar": "3.5.3",
"cli-highlight": "2.1.11",
"co-body": "6.1.0",
"color-convert": "2.0.1",
"content-disposition": "0.5.4",
"date-fns": "2.29.2",
Expand All @@ -62,7 +63,6 @@
"koa": "2.13.4",
"koa-bodyparser": "4.3.0",
"koa-favicon": "2.1.0",
"koa-json-body": "5.3.0",
"koa-logger": "3.2.1",
"koa-mount": "4.0.0",
"koa-send": "5.0.1",
Expand Down Expand Up @@ -126,6 +126,7 @@
"@types/bcryptjs": "2.4.2",
"@types/bull": "3.15.9",
"@types/cbor": "6.0.0",
"@types/co-body": "6.1.3",
"@types/escape-regexp": "0.0.1",
"@types/fluent-ffmpeg": "2.1.20",
"@types/js-yaml": "4.0.5",
Expand Down
15 changes: 0 additions & 15 deletions packages/backend/src/@types/koa-json-body.d.ts

This file was deleted.

70 changes: 65 additions & 5 deletions packages/backend/src/server/activitypub.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Router from '@koa/router';
import json from 'koa-json-body';
import config from '@/config/index.js';
import * as coBody from 'co-body';
import * as crypto from 'node:crypto';
import { IActivity } from '@/remote/activitypub/type.js';
import httpSignature from '@peertube/http-signature';
import Logger from '@/services/logger.js';
import { inspect } from 'util';

import { renderActivity } from '@/remote/activitypub/renderer/index.js';
import renderNote from '@/remote/activitypub/renderer/note.js';
Expand All @@ -20,22 +25,72 @@ import { renderLike } from '@/remote/activitypub/renderer/like.js';
import { getUserKeypair } from '@/misc/keypair-store.js';
import renderFollow from '@/remote/activitypub/renderer/follow.js';

const logger = new Logger('activitypub');

// Init router
const router = new Router();

//#region Routing

function inbox(ctx: Router.RouterContext) {
let signature;
async function inbox(ctx: Router.RouterContext) {
if (ctx.req.headers.host !== config.host) {
ctx.status = 400;
return;
}

// parse body
const { parsed, raw } = await coBody.json(ctx, {
limit: '64kb',
returnRawBody: true,
});
ctx.request.body = parsed;

let signature: httpSignature.IParsedSignature;

try {
signature = httpSignature.parseRequest(ctx.req, { 'headers': [] });
signature = httpSignature.parseRequest(ctx.req, { 'headers': ['(request-target)', 'digest', 'host', 'date'] });
} catch (e) {
logger.warn(`inbox: signature parse error: ${inspect(e)}`);
ctx.status = 401;
return;
}

// Digestヘッダーの検証
const digest = ctx.req.headers.digest;

// 無いとか複数あるとかダメ!
if (typeof digest !== 'string') {
logger.warn(`inbox: unrecognized digest header 1`);
ctx.status = 401;
return;
}

const match = digest.match(/^([0-9A-Za-z-]+)=(.+)$/);

if (match == null) {
logger.warn(`inbox: unrecognized digest header 2`);
ctx.status = 401;
return;
}

const digestAlgo = match[1];
const digestExpected = match[2];

if (digestAlgo.toUpperCase() !== 'SHA-256') {
logger.warn(`inbox: unsupported algorithm`);
ctx.status = 401;
return;
}

const digestActual = crypto.createHash('sha256').update(raw).digest('base64');

if (digestExpected !== digestActual) {
logger.warn(`inbox: digest missmatch`);
ctx.status = 401;
return;
}

processInbox(ctx.request.body, signature);
processInbox(ctx.request.body as IActivity, signature);

ctx.status = 202;
}
Expand All @@ -59,8 +114,13 @@ export function setResponseType(ctx: Router.RouterContext) {
}

// inbox
<<<<<<< HEAD:packages/backend/src/server/activitypub.ts
router.post('/inbox', json(), inbox);
router.post('/users/:user/inbox', json(), inbox);
=======
router.post('/inbox', inbox);
router.post('/users/:user/inbox', inbox);
>>>>>>> 5e385d56d (validate signed headers (#2497)):src/server/activitypub.ts

// note
router.get('/notes/:note', async (ctx, next) => {
Expand Down
35 changes: 18 additions & 17 deletions packages/backend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,14 @@
dependencies:
cbor "*"

"@types/[email protected]":
version "6.1.3"
resolved "https://registry.yarnpkg.com/@types/co-body/-/co-body-6.1.3.tgz#201796c6389066b400cfcb4e1ec5c3db798265a2"
integrity sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==
dependencies:
"@types/node" "*"
"@types/qs" "*"

"@types/color-name@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
Expand Down Expand Up @@ -1985,15 +1993,15 @@ [email protected], cluster-key-slot@^1.1.0:
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==

co-body@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124"
integrity sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ==
co-body@6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.1.0.tgz#d87a8efc3564f9bfe3aced8ef5cd04c7a8766547"
integrity sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==
dependencies:
inflation "^2.0.0"
qs "^6.4.0"
raw-body "^2.2.0"
type-is "^1.6.14"
qs "^6.5.2"
raw-body "^2.3.3"
type-is "^1.6.16"

co-body@^6.0.0:
version "6.0.0"
Expand Down Expand Up @@ -4651,13 +4659,6 @@ [email protected]:
dependencies:
mz "^2.7.0"

[email protected]:
version "5.3.0"
resolved "https://registry.yarnpkg.com/koa-json-body/-/koa-json-body-5.3.0.tgz#64aad3f400adfb81df54b63f7a5eb38bad62d980"
integrity sha1-ZKrT9ACt+4HfVLY/el6zi61i2YA=
dependencies:
co-body "^5.0.0"

[email protected]:
version "3.2.1"
resolved "https://registry.yarnpkg.com/koa-logger/-/koa-logger-3.2.1.tgz#ab9db879526db3837cc9ce4fd983c025b1689f22"
Expand Down Expand Up @@ -6362,7 +6363,7 @@ [email protected]:
pngjs "^5.0.0"
yargs "^15.3.1"

qs@^6.4.0, qs@^6.5.2:
qs@^6.5.2:
version "6.9.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e"
integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==
Expand Down Expand Up @@ -6411,7 +6412,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.4.1.tgz#fa69e94937413382a926aaa17aaeaa6263af4659"
integrity sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ==

raw-body@^2.2.0, raw-body@^2.3.3:
raw-body@^2.3.3:
version "2.4.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==
Expand Down Expand Up @@ -7589,7 +7590,7 @@ type-fest@^0.20.2:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==

type-is@^1.6.14, type-is@^1.6.16, type-is@^1.6.4:
type-is@^1.6.16, type-is@^1.6.4:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
Expand Down

0 comments on commit 5317d27

Please sign in to comment.