From f8661ef95fb1f2c8e0a719028c1e963e98806123 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 18 Dec 2024 17:56:07 +0900 Subject: [PATCH 01/12] Version bump [ci skip] --- CHANGES.md | 6 ++++++ cli/deno.json | 2 +- src/deno.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f4dae86..a522ae4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 1.0.14 +-------------- + +To be released. + + Version 1.0.13 -------------- diff --git a/cli/deno.json b/cli/deno.json index fe7228e..0d5226e 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "1.0.13", + "version": "1.0.14", "license": "MIT", "exports": "./mod.ts", "importMap": "import_map.g.json", diff --git a/src/deno.json b/src/deno.json index 3806687..ec790d6 100644 --- a/src/deno.json +++ b/src/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "1.0.13", + "version": "1.0.14", "license": "MIT", "exports": { ".": "./mod.ts", From 19a754edd709d0fc9563b08a43384888a142959d Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 18 Dec 2024 17:58:45 +0900 Subject: [PATCH 02/12] Version bump [ci skip] --- CHANGES.md | 6 ++++++ cli/deno.json | 2 +- src/deno.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0f6d099..0b19688 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 1.1.11 +-------------- + +To be released. + + Version 1.1.10 -------------- diff --git a/cli/deno.json b/cli/deno.json index 5cee717..c0aa0e0 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "1.1.10", + "version": "1.1.11", "license": "MIT", "exports": "./mod.ts", "importMap": "import_map.g.json", diff --git a/src/deno.json b/src/deno.json index ede600e..71810ed 100644 --- a/src/deno.json +++ b/src/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "1.1.10", + "version": "1.1.11", "license": "MIT", "exports": { ".": "./mod.ts", From a4083bb0e56a942a51aa1d61d9f3998a57549ed5 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 18 Dec 2024 18:08:17 +0900 Subject: [PATCH 03/12] Version bump [ci skip] --- CHANGES.md | 6 ++++++ cli/deno.json | 2 +- src/deno.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e629978..5c4429e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 1.2.11 +-------------- + +To be released. + + Version 1.2.10 -------------- diff --git a/cli/deno.json b/cli/deno.json index a5bd2fe..d2c9a9e 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "1.2.10", + "version": "1.2.11", "license": "MIT", "exports": "./mod.ts", "importMap": "import_map.g.json", diff --git a/src/deno.json b/src/deno.json index 2f2f80a..750008a 100644 --- a/src/deno.json +++ b/src/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "1.2.10", + "version": "1.2.11", "license": "MIT", "exports": { ".": "./mod.ts", From dfc65d03866269ffd470c27fd20304da1c1dd11d Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Mon, 30 Dec 2024 23:49:51 +0900 Subject: [PATCH 04/12] Version bump [ci skip] --- CHANGES.md | 6 ++++++ cli/deno.json | 2 +- src/deno.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0295f36..12d706d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 1.3.4 +------------- + +To be released. + + Version 1.3.3 ------------- diff --git a/cli/deno.json b/cli/deno.json index 2dc7324..1978bef 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "1.3.3", + "version": "1.3.4", "license": "MIT", "exports": "./mod.ts", "importMap": "import_map.g.json", diff --git a/src/deno.json b/src/deno.json index 67576fe..e1413cf 100644 --- a/src/deno.json +++ b/src/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "1.3.3", + "version": "1.3.4", "license": "MIT", "exports": { ".": "./mod.ts", From 49389051b4d8cb760070518d639e55c0d0e1a16a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 1 Jan 2025 12:16:27 +0900 Subject: [PATCH 05/12] Happy New Year! [ci skip] --- CONTRIBUTING.md | 2 +- LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 747b966..389f67b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ Fedify is licensed under the [MIT License]. By opening a pull request, you agree to license your contribution under the MIT License. If you cannot agree to this license, please do not open a pull request. -[MIT License]: https://minhee.mit-license.org/2024/ +[MIT License]: https://minhee.mit-license.org/2024-2025/ ### Building diff --git a/LICENSE b/LICENSE index 946267f..4eb9bdc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright 2024 Hong Minhee +Copyright 2024–2025 Hong Minhee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From e921134dd5097586e4563ea80b9e8d1b5460a645 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sat, 18 Jan 2025 14:03:03 +0900 Subject: [PATCH 06/12] `lookupWebFinger()`: avoid infinite redirection https://github.com/dahlia/fedify/security/advisories/GHSA-c59p-wq67-24wx --- CHANGES.md | 4 ++++ src/webfinger/lookup.test.ts | 18 ++++++++++++++++++ src/webfinger/lookup.ts | 15 ++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a522ae4..e8d8217 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,10 @@ Version 1.0.14 To be released. + - Fixed a security vulnerability where the `lookupWebFinger()` function had + followed the infinite number of redirects, which could lead to a denial of + service attack. Now it follows up to 5 redirects. + Version 1.0.13 -------------- diff --git a/src/webfinger/lookup.test.ts b/src/webfinger/lookup.test.ts index 0630e76..22575d5 100644 --- a/src/webfinger/lookup.test.ts +++ b/src/webfinger/lookup.test.ts @@ -1,4 +1,5 @@ import { assertEquals } from "@std/assert"; +import { deadline } from "@std/async/deadline"; import * as mf from "mock_fetch"; import { test } from "../testing/mod.ts"; import type { ResourceDescriptor } from "./jrd.ts"; @@ -91,6 +92,23 @@ test("lookupWebFinger()", async (t) => { assertEquals(await lookupWebFinger("acct:johndoe@example.com"), expected); }); + mf.mock( + "GET@/.well-known/webfinger", + (_) => + new Response("", { + status: 302, + headers: { Location: "/.well-known/webfinger" }, + }), + ); + + await t.step("infinite redirection", async () => { + const result = await deadline( + lookupWebFinger("acct:johndoe@example.com"), + 2000, + ); + assertEquals(result, null); + }); + mf.uninstall(); }); diff --git a/src/webfinger/lookup.ts b/src/webfinger/lookup.ts index c82f6c4..035f5ea 100644 --- a/src/webfinger/lookup.ts +++ b/src/webfinger/lookup.ts @@ -3,6 +3,8 @@ import type { ResourceDescriptor } from "./jrd.ts"; const logger = getLogger(["fedify", "webfinger", "lookup"]); +const MAX_REDIRECTION = 5; // TODO: Make this configurable. + /** * Looks up a WebFinger resource. * @param resource The resource URL to look up. @@ -26,6 +28,7 @@ export async function lookupWebFinger( } let url = new URL(`${protocol}//${server}/.well-known/webfinger`); url.searchParams.set("resource", resource.href); + let redirected = 0; while (true) { logger.debug( "Fetching WebFinger resource descriptor from {url}...", @@ -48,10 +51,20 @@ export async function lookupWebFinger( response.status >= 300 && response.status < 400 && response.headers.has("Location") ) { - url = new URL( + redirected++; + if (redirected >= MAX_REDIRECTION) { + logger.error( + "Too many redirections ({redirections}) while fetching WebFinger " + + "resource descriptor.", + { redirections: redirected }, + ); + return null; + } + const redirectedUrl = new URL( response.headers.get("Location")!, response.url == null || response.url === "" ? url : response.url, ); + url = redirectedUrl; continue; } if (!response.ok) { From c505eb82fcd6b5b17174c6659c29721bc801ab9a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sat, 18 Jan 2025 14:08:18 +0900 Subject: [PATCH 07/12] Make `lookupWebFinger()` to enforce protocol consistency https://github.com/dahlia/fedify/security/advisories/GHSA-c59p-wq67-24wx --- CHANGES.md | 13 ++++++++++--- src/webfinger/lookup.test.ts | 13 +++++++++++++ src/webfinger/lookup.ts | 12 ++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e8d8217..434c7fc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,9 +8,16 @@ Version 1.0.14 To be released. - - Fixed a security vulnerability where the `lookupWebFinger()` function had - followed the infinite number of redirects, which could lead to a denial of - service attack. Now it follows up to 5 redirects. + - Fixed several security vulnerabilities of the `lookupWebFinger()` function. + + - Fixed a security vulnerability where the `lookupWebFinger()` function + had followed the infinite number of redirects, which could lead to + a denial of service attack. Now it follows up to 5 redirects. + + - Fixed a security vulnerability where the `lookupWebFinger()` function + had followed the redirects to other than the HTTP/HTTPS schemes, which + could lead to a security breach. Now it follows only the same scheme + as the original request. Version 1.0.13 diff --git a/src/webfinger/lookup.test.ts b/src/webfinger/lookup.test.ts index 22575d5..e76ea7f 100644 --- a/src/webfinger/lookup.test.ts +++ b/src/webfinger/lookup.test.ts @@ -109,6 +109,19 @@ test("lookupWebFinger()", async (t) => { assertEquals(result, null); }); + mf.mock( + "GET@/.well-known/webfinger", + (_) => + new Response("", { + status: 302, + headers: { Location: "ftp://example.com/" }, + }), + ); + + await t.step("redirection to different protocol", async () => { + assertEquals(await lookupWebFinger("acct:johndoe@example.com"), null); + }); + mf.uninstall(); }); diff --git a/src/webfinger/lookup.ts b/src/webfinger/lookup.ts index 035f5ea..45952a3 100644 --- a/src/webfinger/lookup.ts +++ b/src/webfinger/lookup.ts @@ -64,6 +64,18 @@ export async function lookupWebFinger( response.headers.get("Location")!, response.url == null || response.url === "" ? url : response.url, ); + if (redirectedUrl.protocol !== url.protocol) { + logger.error( + "Redirected to a different protocol ({protocol} to " + + "{redirectedProtocol}) while fetching WebFinger resource " + + "descriptor.", + { + protocol: url.protocol, + redirectedProtocol: redirectedUrl.protocol, + }, + ); + return null; + } url = redirectedUrl; continue; } From 8be3c2038eebf4ae12481683a1e809b314be3151 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sat, 18 Jan 2025 14:13:27 +0900 Subject: [PATCH 08/12] `lookupWebFinger()`: avoid SSRF attacks https://github.com/dahlia/fedify/security/advisories/GHSA-c59p-wq67-24wx --- CHANGES.md | 5 +++++ src/webfinger/lookup.test.ts | 19 ++++++++++++++++++- src/webfinger/lookup.ts | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 434c7fc..d52cf55 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,11 @@ To be released. could lead to a security breach. Now it follows only the same scheme as the original request. + - Fixed a security vulnerability where the `lookupWebFinger()` function + had followed the redirects to the private network addresses, which + could lead to a SSRF attack. Now it follows only the public network + addresses. + Version 1.0.13 -------------- diff --git a/src/webfinger/lookup.test.ts b/src/webfinger/lookup.test.ts index e76ea7f..b7af79e 100644 --- a/src/webfinger/lookup.test.ts +++ b/src/webfinger/lookup.test.ts @@ -1,6 +1,7 @@ -import { assertEquals } from "@std/assert"; +import { assertEquals, assertRejects } from "@std/assert"; import { deadline } from "@std/async/deadline"; import * as mf from "mock_fetch"; +import { UrlError } from "../runtime/url.ts"; import { test } from "../testing/mod.ts"; import type { ResourceDescriptor } from "./jrd.ts"; import { lookupWebFinger } from "./lookup.ts"; @@ -122,6 +123,22 @@ test("lookupWebFinger()", async (t) => { assertEquals(await lookupWebFinger("acct:johndoe@example.com"), null); }); + mf.mock( + "GET@/.well-known/webfinger", + (_) => + new Response("", { + status: 302, + headers: { Location: "https://localhost/" }, + }), + ); + + await t.step("redirection to private address", async () => { + await assertRejects( + () => lookupWebFinger("acct:johndoe@example.com"), + UrlError, + ); + }); + mf.uninstall(); }); diff --git a/src/webfinger/lookup.ts b/src/webfinger/lookup.ts index 45952a3..5364cb2 100644 --- a/src/webfinger/lookup.ts +++ b/src/webfinger/lookup.ts @@ -1,4 +1,5 @@ import { getLogger } from "@logtape/logtape"; +import { validatePublicUrl } from "../runtime/url.ts"; import type { ResourceDescriptor } from "./jrd.ts"; const logger = getLogger(["fedify", "webfinger", "lookup"]); @@ -35,6 +36,7 @@ export async function lookupWebFinger( { url: url.href }, ); let response: Response; + await validatePublicUrl(url.href); try { response = await fetch(url, { headers: { Accept: "application/jrd+json" }, From fbfe4e13d83ef29a2c3c84f761eefe1ac4d41f1a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Tue, 21 Jan 2025 00:26:10 +0900 Subject: [PATCH 09/12] Release 1.0.14 --- CHANGES.md | 5 ++++- src/runtime/url.ts | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d52cf55..8173a30 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,9 +6,10 @@ Fedify changelog Version 1.0.14 -------------- -To be released. +Released on January 21, 2025. - Fixed several security vulnerabilities of the `lookupWebFinger()` function. + [[CVE-2025-23221]] - Fixed a security vulnerability where the `lookupWebFinger()` function had followed the infinite number of redirects, which could lead to @@ -24,6 +25,8 @@ To be released. could lead to a SSRF attack. Now it follows only the public network addresses. +[CVE-2025-23221]: https://github.com/dahlia/fedify/security/advisories/GHSA-c59p-wq67-24wx + Version 1.0.13 -------------- diff --git a/src/runtime/url.ts b/src/runtime/url.ts index dd95b54..5c8ed2d 100644 --- a/src/runtime/url.ts +++ b/src/runtime/url.ts @@ -1,3 +1,4 @@ +import type { LookupAddress } from "node:dns"; import { lookup } from "node:dns/promises"; import { isIP } from "node:net"; @@ -38,7 +39,12 @@ export async function validatePublicUrl(url: string): Promise { } // To prevent SSRF via DNS rebinding, we need to resolve all IP addresses // and ensure that they are all public: - const addresses = await lookup(hostname, { all: true }); + let addresses: LookupAddress[]; + try { + addresses = await lookup(hostname, { all: true }); + } catch { + addresses = []; + } for (const { address, family } of addresses) { if ( family === 4 && !isValidPublicIPv4Address(address) || From e06d8732d0f9a9a61f8b9578b3fb98e8ee0fd711 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Tue, 21 Jan 2025 00:52:55 +0900 Subject: [PATCH 10/12] Release 1.1.11 --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b88d9de..74f4db4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ Fedify changelog Version 1.1.11 -------------- -To be released. +Released on January 21, 2025. - Fixed several security vulnerabilities of the `lookupWebFinger()` function. [[CVE-2025-23221]] From d47268b1a1a2297ee323da13eccbe707c5c9dc55 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Tue, 21 Jan 2025 00:55:00 +0900 Subject: [PATCH 11/12] Release 1.2.11 --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f090791..29d2c22 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ Fedify changelog Version 1.2.11 -------------- -To be released. +Released on January 21, 2025. - Fixed several security vulnerabilities of the `lookupWebFinger()` function. [[CVE-2025-23221]] From 91bd1d7e9a212d3b6733d7eb0c45d7aa7b64d279 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Tue, 21 Jan 2025 00:59:40 +0900 Subject: [PATCH 12/12] Release 1.3.4 --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 14ac0df..bc96c99 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ Fedify changelog Version 1.3.4 ------------- -To be released. +Released on January 21, 2025. - Fixed several security vulnerabilities of the `lookupWebFinger()` function. [[CVE-2025-23221]]