Skip to content

Commit

Permalink
lookupWebFinger(): avoid SSRF attacks
Browse files Browse the repository at this point in the history
  • Loading branch information
dahlia committed Jan 18, 2025
1 parent c505eb8 commit 8be3c20
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------------
Expand Down
19 changes: 18 additions & 1 deletion src/webfinger/lookup.test.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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();
});

Expand Down
2 changes: 2 additions & 0 deletions src/webfinger/lookup.ts
Original file line number Diff line number Diff line change
@@ -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"]);
Expand Down Expand Up @@ -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" },
Expand Down

0 comments on commit 8be3c20

Please sign in to comment.