From 354208b49f8074ba8da1927bb05005c6a9abd096 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 28 Jul 2024 16:17:13 +0200 Subject: [PATCH] fix (backend): limit node-fetch responses to a reasonable length in all places Co-authored-by: naskya --- packages/backend/src/misc/fetch.ts | 3 +-- .../remote/activitypub/misc/ld-signature.ts | 1 + .../src/remote/activitypub/models/person.ts | 23 +++++++++++-------- .../src/services/fetch-instance-metadata.ts | 1 + 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts index 5af3b08fa5..da3b5750ee 100644 --- a/packages/backend/src/misc/fetch.ts +++ b/packages/backend/src/misc/fetch.ts @@ -57,7 +57,6 @@ export async function getResponse(args: { body?: string; headers: Record; timeout?: number; - size?: number; redirect?: RequestRedirect; }) { if (!isSafeUrl(args.url)) { @@ -76,7 +75,7 @@ export async function getResponse(args: { headers: args.headers, body: args.body, timeout, - size: args.size || 10 * 1024 * 1024, + size: 10 * 1024 * 1024, agent: getAgentByUrl, signal: controller.signal, redirect: args.redirect, diff --git a/packages/backend/src/remote/activitypub/misc/ld-signature.ts b/packages/backend/src/remote/activitypub/misc/ld-signature.ts index 2d1e7ef6b2..b654e89767 100644 --- a/packages/backend/src/remote/activitypub/misc/ld-signature.ts +++ b/packages/backend/src/remote/activitypub/misc/ld-signature.ts @@ -126,6 +126,7 @@ export class LdSignature { headers: { Accept: "application/ld+json, application/json", }, + size: 1024 * 1024, // 1MiB // TODO //timeout: this.loderTimeout, agent: (u) => (u.protocol === "http:" ? httpAgent : httpsAgent), diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 8a94af4bed..e9c1b5bd1b 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -17,7 +17,6 @@ import { User } from "@/models/entities/user.js"; import type { Emoji } from "@/models/entities/emoji.js"; import { UserNotePining } from "@/models/entities/user-note-pining.js"; import { - genId, genIdAt, InternalEvent, isSameOrigin, @@ -52,6 +51,7 @@ import { extractApHashtags } from "./tag.js"; import { resolveNote, extractEmojis } from "./note.js"; import { resolveImage } from "./image.js"; import { inspect } from "node:util"; +import fetch from "node-fetch"; const nameLength = 128; const summaryLength = 2048; @@ -207,6 +207,7 @@ export async function createPerson( try { const data = await fetch(person.followers, { headers: { Accept: "application/json" }, + size: 1024 * 1024 }); const json_data = JSON.parse(await data.text()); @@ -222,6 +223,7 @@ export async function createPerson( try { const data = await fetch(person.following, { headers: { Accept: "application/json" }, + size: 1024 * 1024 }); const json_data = JSON.parse(await data.text()); @@ -488,10 +490,11 @@ export async function updatePerson( if (typeof person.followers === "string") { try { - let data = await fetch(person.followers, { + const data = await fetch(person.followers, { headers: { Accept: "application/json" }, + size: 1024 * 1024 }); - let json_data = JSON.parse(await data.text()); + const json_data = JSON.parse(await data.text()); followersCount = json_data.totalItems; } catch { @@ -503,10 +506,11 @@ export async function updatePerson( if (typeof person.following === "string") { try { - let data = await fetch(person.following, { + const data = await fetch(person.following, { headers: { Accept: "application/json" }, + size: 1024 * 1024 }); - let json_data = JSON.parse(await data.text()); + const json_data = JSON.parse(await data.text()); followingCount = json_data.totalItems; } catch { @@ -518,10 +522,10 @@ export async function updatePerson( if (typeof person.outbox === "string") { try { - let data = await fetch(person.outbox, { + const data = await fetch(person.outbox, { headers: { Accept: "application/json" }, }); - let json_data = JSON.parse(await data.text()); + const json_data = JSON.parse(await data.text()); notesCount = json_data.totalItems; } catch (e) { @@ -725,9 +729,10 @@ export async function updateFeatured(userId: User["id"], resolver?: Resolver) { let td = 0; for (const note of featuredNotes.filter((note) => note != null)) { td -= 1000; + const createdAt = new Date(Date.now() + td); transactionalEntityManager.insert(UserNotePining, { - id: genId(new Date(Date.now() + td)), - createdAt: new Date(), + id: genIdAt(createdAt), + createdAt, userId: user.id, noteId: note!.id, }); diff --git a/packages/backend/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts index 58d7ae338e..494027a37c 100644 --- a/packages/backend/src/services/fetch-instance-metadata.ts +++ b/packages/backend/src/services/fetch-instance-metadata.ts @@ -156,6 +156,7 @@ async function fetchFaviconUrl( // TODO //timeout: 10000, agent: getAgentByUrl, + size: 1024 * 1024 }); if (favicon.ok) {