Loading CHANGES.md +4 −0 Original line number Diff line number Diff line Loading @@ -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 -------------- Loading src/webfinger/lookup.test.ts +18 −0 Original line number Diff line number Diff line 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"; Loading Loading @@ -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(); }); Loading src/webfinger/lookup.ts +14 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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}...", Loading @@ -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) { Loading Loading
CHANGES.md +4 −0 Original line number Diff line number Diff line Loading @@ -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 -------------- Loading
src/webfinger/lookup.test.ts +18 −0 Original line number Diff line number Diff line 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"; Loading Loading @@ -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(); }); Loading
src/webfinger/lookup.ts +14 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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}...", Loading @@ -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) { Loading