@fedify/fedify 0.12.0-dev.301 → 0.12.0-dev.302

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGES.md CHANGED
@@ -98,14 +98,23 @@ To be released.
98
98
  - Removed `verify()` function.
99
99
  - Removed `VerifyOptions` interface.
100
100
 
101
+ - Fixed a bug where the `lookupWebFinger()` function had incorrectly queried
102
+ if the given `resource` was a URL starts with `http:` or had a non-default
103
+ port number.
104
+
101
105
  - Fixed a SSRF vulnerability in the built-in document loader.
102
106
  [[CVE-2024-39687]]
103
107
 
104
108
  - The `fetchDocumentLoader()` function now throws an error when the given
105
109
  URL is not an HTTP or HTTPS URL or refers to a private network address.
110
+ - Added an optional second parameter to the `fetchDocumentLoader()`
111
+ function, which can be used to allow fetching private network addresses.
106
112
  - The `getAuthenticatedDocumentLoader()` function now returns a document
107
113
  loader that throws an error when the given URL is not an HTTP or HTTPS
108
114
  URL or refers to a private network address.
115
+ - Added an optional second parameter to
116
+ the `getAuthenticatedDocumentLoader()` function, which can be used to
117
+ allow fetching private network addresses.
109
118
 
110
119
  - Added `@fedify/fedify/x/astro` module for integrating with [Astro]
111
120
  middleware. [[#50]]
@@ -4,7 +4,7 @@ import { getLogger } from "@logtape/logtape";
4
4
  import { signRequest } from "../sig/http.js";
5
5
  import { validateCryptoKey } from "../sig/key.js";
6
6
  import preloadedContexts from "./contexts.js";
7
- import { validatePublicUrl } from "./url.js";
7
+ import { UrlError, validatePublicUrl } from "./url.js";
8
8
  const logger = getLogger(["fedify", "runtime", "docloader"]);
9
9
  /**
10
10
  * Error thrown when fetching a JSON-LD document failed.
@@ -85,9 +85,11 @@ async function getRemoteDocument(url, response) {
85
85
  * - <https://www.w3.org/ns/did/v1>
86
86
  * - <https://w3id.org/security/multikey/v1>
87
87
  * @param url The URL of the document to load.
88
+ * @param allowPrivateAddress Whether to allow fetching private network
89
+ * addresses. Turned off by default.
88
90
  * @returns The remote document.
89
91
  */
90
- export async function fetchDocumentLoader(url) {
92
+ export async function fetchDocumentLoader(url, allowPrivateAddress = false) {
91
93
  if (url in preloadedContexts) {
92
94
  logger.debug("Using preloaded context: {url}.", { url });
93
95
  return {
@@ -96,7 +98,17 @@ export async function fetchDocumentLoader(url) {
96
98
  documentUrl: url,
97
99
  };
98
100
  }
99
- await validatePublicUrl(url);
101
+ if (!allowPrivateAddress) {
102
+ try {
103
+ await validatePublicUrl(url);
104
+ }
105
+ catch (error) {
106
+ if (error instanceof UrlError) {
107
+ logger.error("Disallowed private URL: {url}", { url, error });
108
+ }
109
+ throw error;
110
+ }
111
+ }
100
112
  const request = createRequest(url);
101
113
  logRequest(request);
102
114
  const response = await fetch(request, {
@@ -118,14 +130,26 @@ export async function fetchDocumentLoader(url) {
118
130
  * the fetched documents.
119
131
  * @param identity The identity to get the document loader for.
120
132
  * The actor's key pair.
133
+ * @param allowPrivateAddress Whether to allow fetching private network
134
+ * addresses. Turned off by default.
121
135
  * @returns The authenticated document loader.
122
136
  * @throws {TypeError} If the key is invalid or unsupported.
123
137
  * @since 0.4.0
124
138
  */
125
- export function getAuthenticatedDocumentLoader(identity) {
139
+ export function getAuthenticatedDocumentLoader(identity, allowPrivateAddress = false) {
126
140
  validateCryptoKey(identity.privateKey);
127
141
  async function load(url) {
128
- await validatePublicUrl(url);
142
+ if (!allowPrivateAddress) {
143
+ try {
144
+ await validatePublicUrl(url);
145
+ }
146
+ catch (error) {
147
+ if (error instanceof UrlError) {
148
+ logger.error("Disallowed private URL: {url}", { url, error });
149
+ }
150
+ throw error;
151
+ }
152
+ }
129
153
  let request = createRequest(url);
130
154
  request = await signRequest(request, identity.privateKey, identity.keyId);
131
155
  logRequest(request);
@@ -9,6 +9,7 @@ const logger = getLogger(["fedify", "webfinger", "lookup"]);
9
9
  export async function lookupWebFinger(resource) {
10
10
  if (typeof resource === "string")
11
11
  resource = new URL(resource);
12
+ let protocol = "https:";
12
13
  let server;
13
14
  if (resource.protocol === "acct:") {
14
15
  const atPos = resource.pathname.lastIndexOf("@");
@@ -19,9 +20,10 @@ export async function lookupWebFinger(resource) {
19
20
  return null;
20
21
  }
21
22
  else {
22
- server = resource.hostname;
23
+ protocol = resource.protocol;
24
+ server = resource.host;
23
25
  }
24
- let url = new URL(`https://${server}/.well-known/webfinger`);
26
+ let url = new URL(`${protocol}//${server}/.well-known/webfinger`);
25
27
  url.searchParams.set("resource", resource.href);
26
28
  while (true) {
27
29
  logger.debug("Fetching WebFinger resource descriptor from {url}...", { url: url.href });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/fedify",
3
- "version": "0.12.0-dev.301+e2b9f0c7",
3
+ "version": "0.12.0-dev.302+3ef9e026",
4
4
  "description": "An ActivityPub server framework",
5
5
  "keywords": [
6
6
  "ActivityPub",
@@ -65,15 +65,19 @@ export declare class FetchError extends Error {
65
65
  * - <https://www.w3.org/ns/did/v1>
66
66
  * - <https://w3id.org/security/multikey/v1>
67
67
  * @param url The URL of the document to load.
68
+ * @param allowPrivateAddress Whether to allow fetching private network
69
+ * addresses. Turned off by default.
68
70
  * @returns The remote document.
69
71
  */
70
- export declare function fetchDocumentLoader(url: string): Promise<RemoteDocument>;
72
+ export declare function fetchDocumentLoader(url: string, allowPrivateAddress?: boolean): Promise<RemoteDocument>;
71
73
  /**
72
74
  * Gets an authenticated {@link DocumentLoader} for the given identity.
73
75
  * Note that an authenticated document loader intentionally does not cache
74
76
  * the fetched documents.
75
77
  * @param identity The identity to get the document loader for.
76
78
  * The actor's key pair.
79
+ * @param allowPrivateAddress Whether to allow fetching private network
80
+ * addresses. Turned off by default.
77
81
  * @returns The authenticated document loader.
78
82
  * @throws {TypeError} If the key is invalid or unsupported.
79
83
  * @since 0.4.0
@@ -81,7 +85,7 @@ export declare function fetchDocumentLoader(url: string): Promise<RemoteDocument
81
85
  export declare function getAuthenticatedDocumentLoader(identity: {
82
86
  keyId: URL;
83
87
  privateKey: dntShim.CryptoKey;
84
- }): DocumentLoader;
88
+ }, allowPrivateAddress?: boolean): DocumentLoader;
85
89
  /**
86
90
  * The parameters for {@link kvCache} function.
87
91
  */
@@ -1 +1 @@
1
- {"version":3,"file":"docloader.d.ts","sourceRoot":"","sources":["../../src/runtime/docloader.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAQ1D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,MAAM,MAAM,kCAAkC,GAAG,CAC/C,QAAQ,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAA;CAAE,KACpD,cAAc,CAAC;AAEpB;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;;;;OAKG;gBACS,GAAG,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAKhD;AAoED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CA0BzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAA;CAAE,GACtD,cAAc,CAuBhB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,EAAE,EAAE,OAAO,CAAC;IAEZ;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC;IAEf;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC1E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAC/C,cAAc,CA2ChB"}
1
+ {"version":3,"file":"docloader.d.ts","sourceRoot":"","sources":["../../src/runtime/docloader.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAQ1D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,MAAM,MAAM,kCAAkC,GAAG,CAC/C,QAAQ,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAA;CAAE,KACpD,cAAc,CAAC;AAEpB;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;;;;OAKG;gBACS,GAAG,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAKhD;AAoED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,mBAAmB,GAAE,OAAe,GACnC,OAAO,CAAC,cAAc,CAAC,CAmCzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAA;CAAE,EACvD,mBAAmB,GAAE,OAAe,GACnC,cAAc,CAgChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,EAAE,EAAE,OAAO,CAAC;IAEZ;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC;IAEf;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC1E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAC/C,cAAc,CA2ChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/webfinger/lookup.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,GAAG,GAAG,MAAM,GACrB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAqDpC"}
1
+ {"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/webfinger/lookup.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,GAAG,GAAG,MAAM,GACrB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAuDpC"}