@fedify/fedify 0.12.0-dev.300 → 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]]
|
package/esm/runtime/docloader.js
CHANGED
@@ -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
|
-
|
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
|
-
|
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);
|
package/esm/webfinger/lookup.js
CHANGED
@@ -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
|
-
|
23
|
+
protocol = resource.protocol;
|
24
|
+
server = resource.host;
|
23
25
|
}
|
24
|
-
let url = new URL(
|
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
@@ -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
|
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,
|
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"}
|