WIP: Secure mode #31

Closed
norm wants to merge 21 commits from (deleted):feat/secure-fetch into main
7 changed files with 19 additions and 20 deletions
Showing only changes of commit b4582a829f - Show all commits

View file

@ -7,7 +7,6 @@ import { toPuny } from '@/misc/convert-host.js';
import DbResolver from '@/remote/activitypub/db-resolver.js';
import { getApId } from '@/remote/activitypub/type.js';
export default async function checkFetch(req: IncomingMessage): Promise<number> {
Johann150 marked this conversation as resolved
Review

If you want you could maybe take a stab at reusing this in packages/backend/src/queue/processors/inbox.ts since its essentially the same code for validating a HTTP signature.

If you want you could maybe take a stab at reusing this in `packages/backend/src/queue/processors/inbox.ts` since its essentially the same code for validating a HTTP signature.
Review

Not enitrely sure how to extract out the common logic here, may leave it to someone else to handle that.

Not enitrely sure how to extract out the common logic here, may leave it to someone else to handle that.
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {

View file

@ -70,7 +70,7 @@ router.get('/notes/:note', async (ctx, next) => {
if (!isActivityPubReq(ctx)) return await next();
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -87,7 +87,7 @@ router.get('/notes/:note', async (ctx, next) => {
}
// リモートだったらリダイレクト
if (note.userHost != null) {
if (note.userHost !== null) {
if (note.uri == null || isSelfHost(note.userHost)) {
ctx.status = 500;
return;
@ -110,7 +110,7 @@ router.get('/notes/:note', async (ctx, next) => {
// note activity
router.get('/notes/:note/activity', async ctx => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -160,7 +160,7 @@ router.get('/users/:user/publickey', async ctx => {
}
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -220,7 +220,7 @@ router.get('/users/:user', async (ctx, next) => {
}
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -246,7 +246,7 @@ router.get('/@:user', async (ctx, next) => {
}
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -269,7 +269,7 @@ router.get('/actor', async (ctx, next) => {
// emoji
router.get('/emojis/:emoji', async ctx => {
const verify = await checkFetch(ctx.req);
norm marked this conversation as resolved Outdated

I think emojis are often not proxied by servers so clients will try to load the emoji from the original server. With requiring HTTP signatures even for this that will cause problems.

I think emojis are often not proxied by servers so clients will try to load the emoji from the original server. With requiring HTTP signatures even for this that will cause problems.
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -297,7 +297,7 @@ router.get('/emojis/:emoji', async ctx => {
// like
router.get('/likes/:like', async ctx => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -329,7 +329,7 @@ router.get('/likes/:like', async ctx => {
// follow
router.get('/follows/:follower/:followee', async ctx => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}

View file

@ -11,7 +11,7 @@ import { fetchMeta } from '@/misc/fetch-meta.js';
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}

View file

@ -14,7 +14,7 @@ import { fetchMeta } from '@/misc/fetch-meta.js';
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -22,7 +22,7 @@ export default async (ctx: Router.RouterContext) => {
const userId = ctx.params.user;
const cursor = ctx.request.query.cursor;
if (cursor != null && typeof cursor !== 'string') {
if (cursor !== null && typeof cursor !== 'string') {
ctx.status = 400;
return;
}

View file

@ -14,7 +14,7 @@ import { fetchMeta } from '@/misc/fetch-meta.js';
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -22,7 +22,7 @@ export default async (ctx: Router.RouterContext) => {
const userId = ctx.params.user;
const cursor = ctx.request.query.cursor;
if (cursor != null && typeof cursor !== 'string') {
if (cursor !== null && typeof cursor !== 'string') {
ctx.status = 400;
return;
}

View file

@ -18,7 +18,7 @@ import { fetchMeta } from '@/misc/fetch-meta.js';
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
if (verify != 200) {
if (verify !== 200) {
ctx.status = verify;
return;
}
@ -26,20 +26,20 @@ export default async (ctx: Router.RouterContext) => {
const userId = ctx.params.user;
const sinceId = ctx.request.query.since_id;
if (sinceId != null && typeof sinceId !== 'string') {
if (sinceId !== null && typeof sinceId !== 'string') {
ctx.status = 400;
return;
}
const untilId = ctx.request.query.until_id;
if (untilId != null && typeof untilId !== 'string') {
if (untilId !== null && typeof untilId !== 'string') {
ctx.status = 400;
return;
}
const page = ctx.request.query.page === 'true';
if (countIf(x => x != null, [sinceId, untilId]) > 1) {
if (countIf(x => x !== null, [sinceId, untilId]) > 1) {
ctx.status = 400;
return;
}

View file

@ -55,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
.andWhere('note.id IN (SELECT id FROM note_replies(:noteId, :depth, :limit))', { noteId: ps.noteId, depth: ps.depth, limit: ps.limit })
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
.leftJoinAndSelect('user.banner', 'banner');
generateVisibilityQuery(query, user);
if (user) {