diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-07-08 11:27:31 -0400 |
|---|---|---|
| committer | dakkar <dakkar@thenautilus.net> | 2025-07-27 19:39:20 +0100 |
| commit | 3c59a7ae01f7ea7094178cf961c3f4a668672f08 (patch) | |
| tree | f0310bd53666b20223339c3fd269defa655611a3 /packages/backend/src/core/HttpRequestService.ts | |
| parent | refactor actor validation to reduce code duplication (diff) | |
| download | sharkey-3c59a7ae01f7ea7094178cf961c3f4a668672f08.tar.gz sharkey-3c59a7ae01f7ea7094178cf961c3f4a668672f08.tar.bz2 sharkey-3c59a7ae01f7ea7094178cf961c3f4a668672f08.zip | |
allow HTTP connections to private IPs
Diffstat (limited to 'packages/backend/src/core/HttpRequestService.ts')
| -rw-r--r-- | packages/backend/src/core/HttpRequestService.ts | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/packages/backend/src/core/HttpRequestService.ts b/packages/backend/src/core/HttpRequestService.ts index 046b0dc244..bbc127fa86 100644 --- a/packages/backend/src/core/HttpRequestService.ts +++ b/packages/backend/src/core/HttpRequestService.ts @@ -20,7 +20,6 @@ import type { IObject, IObjectWithId } from '@/core/activitypub/type.js'; import { UtilityService } from '@/core/UtilityService.js'; import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js'; import type { Response } from 'node-fetch'; -import type { URL } from 'node:url'; import type { Socket } from 'node:net'; export type HttpRequestSendOptions = { @@ -28,6 +27,15 @@ export type HttpRequestSendOptions = { validators?: ((res: Response) => void)[]; }; +export function isPrivateUrl(url: URL): boolean { + if (!ipaddr.isValid(url.hostname)) { + return false; + } + + const ip = ipaddr.parse(url.hostname); + return ip.range() !== 'unicast'; +} + export function isPrivateIp(allowedPrivateNetworks: PrivateNetwork[] | undefined, ip: string, port?: number): boolean { const parsedIp = ipaddr.parse(ip); @@ -303,6 +311,7 @@ export class HttpRequestService { timeout?: number, size?: number, isLocalAddressAllowed?: boolean, + allowHttp?: boolean, } = {}, extra: HttpRequestSendOptions = { throwErrorWhenResponseNotOk: true, @@ -311,7 +320,9 @@ export class HttpRequestService { ): Promise<Response> { const timeout = args.timeout ?? 5000; - this.utilityService.assertUrl(url); + const parsedUrl = new URL(url); + const allowHttp = args.allowHttp || isPrivateUrl(parsedUrl); + this.utilityService.assertUrl(parsedUrl, allowHttp); const controller = new AbortController(); setTimeout(() => { @@ -320,7 +331,7 @@ export class HttpRequestService { const isLocalAddressAllowed = args.isLocalAddressAllowed ?? false; - const res = await fetch(url, { + const res = await fetch(parsedUrl, { method: args.method ?? 'GET', headers: { 'User-Agent': this.config.userAgent, |