diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts index e9975f3486..83680c175f 100644 --- a/packages/backend/src/misc/download-url.ts +++ b/packages/backend/src/misc/download-url.ts @@ -92,7 +92,7 @@ export async function downloadUrl(url: string, path: string): Promise { logger.succ(`Download finished: ${chalk.cyan(url)}`); } -function isPrivateIp(ip: string): boolean { +export function isPrivateIp(ip: string): boolean { for (const net of config.allowedPrivateNetworks || []) { const cidr = new IPCIDR(net); if (cidr.contains(ip)) { diff --git a/packages/backend/src/services/drive/upload-from-url.ts b/packages/backend/src/services/drive/upload-from-url.ts index 6e6059960f..abbefbbf6b 100644 --- a/packages/backend/src/services/drive/upload-from-url.ts +++ b/packages/backend/src/services/drive/upload-from-url.ts @@ -1,7 +1,7 @@ import { URL } from "node:url"; import type { User } from "@/models/entities/user.js"; import { createTemp } from "@/misc/create-temp.js"; -import { downloadUrl } from "@/misc/download-url.js"; +import { downloadUrl, isPrivateIp } from "@/misc/download-url.js"; import type { DriveFolder } from "@/models/entities/drive-folder.js"; import type { DriveFile } from "@/models/entities/drive-file.js"; import { DriveFiles } from "@/models/index.js"; @@ -23,10 +23,6 @@ type Args = { requestHeaders?: Record | null; }; -const PRIVATE_IPV4 = - /(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)|(^0\.)/; -const PRIVATE_IPV6 = /(f[c-e][0-9a-f][0-9a-f]:)|(F[C-E][0-9A-F][0-9A-F]:)|(::)/; - export async function uploadFromUrl({ url, user, @@ -42,9 +38,7 @@ export async function uploadFromUrl({ const parsedUrl = new URL(url); if ( process.env.NODE_ENV === "production" && - (PRIVATE_IPV4.test(parsedUrl.hostname) || - PRIVATE_IPV6.test(parsedUrl.hostname) || - parsedUrl.hostname.includes("localhost")) + isPrivateIp(parsedUrl.hostname) ) { throw new Error("Private IP is not allowed"); }