Skip to content

Commit

Permalink
validate signed headers (#2497)
Browse files Browse the repository at this point in the history
* validate signed headers

* リクエストホスト

Co-authored-by: perillamint <perillamint@silicon.moe>
Co-authored-by: yunochi <yuno@yunochi.com>
Co-authored-by: Laura Hausmann <laura@hausmann.dev>
  • Loading branch information
4 people authored and fs5m8 committed Nov 28, 2023
1 parent 8f71cf3 commit d4710e6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 40 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"cbor": "9.0.1",
"chalk": "4.1.2",
"cli-highlight": "2.1.11",
"co-body": "6.1.0",
"content-disposition": "0.5.4",
"crc-32": "1.2.2",
"cross-env": "7.0.3",
Expand Down Expand Up @@ -99,7 +100,6 @@
"koa": "2.14.2",
"koa-bodyparser": "4.4.1",
"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 @@ -201,6 +201,7 @@
"@types/bcryptjs": "2.4.6",
"@types/bull": "4.10.0",
"@types/cbor": "6.0.0",
"@types/co-body": "6.1.3",
"@types/dateformat": "3.0.1",
"@types/double-ended-queue": "2.1.7",
"@types/escape-regexp": "0.0.3",
Expand Down
15 changes: 0 additions & 15 deletions src/@types/koa-json-body.d.ts

This file was deleted.

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

import { renderActivity } from '../remote/activitypub/renderer';
import renderNote from '../remote/activitypub/renderer/note';
Expand All @@ -18,22 +23,72 @@ import { ILocalUser, User } from '../models/entities/user';
import { In } from 'typeorm';
import { ensure } from '../prelude/ensure';

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,8 @@ export function setResponseType(ctx: Router.RouterContext) {
}

// inbox
router.post('/inbox', json({ limit: '64kb' }), inbox);
router.post('/users/:user/inbox', json({ limit: '64kb' }), inbox);
router.post('/inbox', inbox);
router.post('/users/:user/inbox', inbox);

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

"@types/co-body@6.1.3":
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 @@ -2692,15 +2700,15 @@ 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 @@ -5904,13 +5912,6 @@ koa-favicon@2.1.0:
dependencies:
mz "^2.7.0"

koa-json-body@5.3.0:
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"

koa-logger@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/koa-logger/-/koa-logger-3.2.1.tgz#ab9db879526db3837cc9ce4fd983c025b1689f22"
Expand Down Expand Up @@ -7983,7 +7984,7 @@ qrcode@1.5.3:
pngjs "^5.0.0"
yargs "^15.3.1"

qs@^6.4.0, qs@^6.5.2:
qs@^6.5.2:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
Expand Down Expand Up @@ -8039,7 +8040,7 @@ ratelimiter@3.4.1:
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 @@ -9576,7 +9577,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.18, type-is@^1.6.4:
type-is@^1.6.16, type-is@^1.6.18, 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 d4710e6

Please sign in to comment.