@commonpub/server 2.53.1 → 2.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,247 +1,12 @@
1
- /** SSRF protection for content import / remote-asset fetches. */
2
- import net from 'node:net';
3
- // Tested against the raw hostname string (a strict superset of the
4
- // pre-existing patterns — preserves blocking of names like `127.0.0.1.x`).
5
- const PRIVATE_HOST_PATTERNS = [
6
- /^127\./,
7
- /^10\./,
8
- /^172\.(1[6-9]|2\d|3[01])\./,
9
- /^192\.168\./,
10
- /^169\.254\./,
11
- /^0\./,
12
- /^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./,
13
- /^198\.1[89]\./,
14
- /^192\.0\.0\./,
15
- /^192\.0\.2\./,
16
- /^198\.51\.100\./,
17
- /^203\.0\.113\./,
18
- /^22[4-9]\./, // 224.0.0.0+ multicast / reserved
19
- /^23\d\./,
20
- /^24\d\./,
21
- /^25[0-5]\./,
22
- /^::1$/,
23
- /^::$/,
24
- /^::ffff:/i, // IPv4-mapped IPv6
25
- /^fc/i, // IPv6 unique-local
26
- /^fd/i,
27
- /^fe80/i, // IPv6 link-local
28
- /^ff/i, // IPv6 multicast
29
- ];
30
- const PRIVATE_IPV4_PATTERNS = [
31
- /^127\./,
32
- /^10\./,
33
- /^172\.(1[6-9]|2\d|3[01])\./,
34
- /^192\.168\./,
35
- /^169\.254\./,
36
- /^0\./,
37
- /^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./,
38
- /^198\.1[89]\./,
39
- /^192\.0\.0\./,
40
- /^192\.0\.2\./,
41
- /^198\.51\.100\./,
42
- /^203\.0\.113\./,
43
- /^22[4-9]\./,
44
- /^23\d\./,
45
- /^24\d\./,
46
- /^25[0-5]\./,
47
- ];
48
- const BLOCKED_HOSTNAMES = new Set([
49
- 'localhost',
50
- 'localhost.localdomain',
51
- 'metadata.google.internal',
52
- 'metadata.internal',
53
- ]);
54
- /** Classify a literal IP (v4, v6, or IPv4-mapped IPv6) as private/reserved. */
55
- export function isPrivateIp(ip) {
56
- let addr = ip.trim().toLowerCase().replace(/^\[|\]$/g, '').replace(/%.*$/, '');
57
- const mapped = addr.match(/^(?:::ffff:|::)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
58
- if (mapped)
59
- addr = mapped[1];
60
- const fam = net.isIP(addr);
61
- if (fam === 4)
62
- return PRIVATE_IPV4_PATTERNS.some((p) => p.test(addr));
63
- if (fam === 6) {
64
- if (addr === '::1' || addr === '::')
65
- return true;
66
- if (/^f[cd]/.test(addr))
67
- return true; // fc00::/7 unique-local
68
- if (/^fe[89ab]/.test(addr))
69
- return true; // fe80::/10 link-local
70
- if (/^ff/.test(addr))
71
- return true; // ff00::/8 multicast
72
- return false;
73
- }
74
- return false;
75
- }
76
1
  /**
77
- * Reject numeric-host SSRF encodings that `new URL()` accepts but no
78
- * legitimate public host uses: dotless decimal (2130706433), dotless/segmented
79
- * hex (0x7f000001 / 0x7f.0.0.1), or octal-leading segments (0177.0.0.1).
80
- */
81
- function isSuspiciousNumericHost(host) {
82
- if (/^\d+$/.test(host))
83
- return true;
84
- if (/^0x[0-9a-f]+$/i.test(host))
85
- return true;
86
- if (/^0\d+(\.\d+){0,3}$/.test(host))
87
- return true;
88
- if (/^0x[0-9a-f]+(\.[0-9a-fx]+){0,3}$/i.test(host))
89
- return true;
90
- return false;
91
- }
92
- /**
93
- * Synchronous, string-level SSRF check. Blocks malformed URLs, non-HTTP(S)
94
- * schemes, blocked hostnames, literal private/reserved IPs (v4, v6,
95
- * IPv4-mapped), and numeric-encoding bypasses.
2
+ * SSRF protection re-export shim.
96
3
  *
97
- * NOTE: this does not resolve DNS, so a public hostname whose A/AAAA record
98
- * points at a private address (DNS-rebinding) is NOT caught here. Redirect
99
- * targets are re-validated by `fetchWithRedirectValidation`. Closing the
100
- * DNS-rebinding gap requires connection-pinned resolution (undici dispatcher
101
- * with a fixed lookup) tracked as a follow-up.
102
- */
103
- export function isPrivateUrl(urlString) {
104
- let parsed;
105
- try {
106
- parsed = new URL(urlString);
107
- }
108
- catch {
109
- return true;
110
- }
111
- if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
112
- return true;
113
- }
114
- const hostname = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, '');
115
- if (!hostname)
116
- return true;
117
- if (BLOCKED_HOSTNAMES.has(hostname))
118
- return true;
119
- if (isSuspiciousNumericHost(hostname))
120
- return true;
121
- // String-prefix check (superset of the original behavior — also blocks
122
- // names crafted as `127.0.0.1.evil.com`).
123
- if (PRIVATE_HOST_PATTERNS.some((p) => p.test(hostname)))
124
- return true;
125
- // Literal-IP check catches normalized forms the string regex misses
126
- // (e.g. IPv4-mapped IPv6 `::ffff:7f00:1`).
127
- if (net.isIP(hostname) && isPrivateIp(hostname))
128
- return true;
129
- return false;
130
- }
131
- const MAX_RESPONSE_SIZE = 10 * 1024 * 1024; // 10 MB
132
- const FETCH_TIMEOUT_MS = 30_000;
133
- const MAX_REDIRECTS = 5;
134
- /**
135
- * Stream a Response body into a Buffer, aborting if it exceeds maxSize.
136
- * Avoids the "buffer everything, then check" pattern that allows a
137
- * malicious upstream with chunked encoding (no Content-Length) to OOM us.
138
- *
139
- * Falls back to `arrayBuffer()` when `response.body` is unavailable
140
- * (test mocks, HEAD responses, 304s) — the size check still applies after
141
- * the buffer is materialised.
142
- */
143
- async function streamBoundedBody(response, maxSize) {
144
- if (!response.body) {
145
- const buf = Buffer.from(await response.arrayBuffer());
146
- if (buf.byteLength > maxSize)
147
- throw new Error('Response too large');
148
- return buf;
149
- }
150
- const reader = response.body.getReader();
151
- let total = 0;
152
- const chunks = [];
153
- try {
154
- while (true) {
155
- const { done, value } = await reader.read();
156
- if (done)
157
- break;
158
- total += value.length;
159
- if (total > maxSize) {
160
- await reader.cancel();
161
- throw new Error('Response too large');
162
- }
163
- chunks.push(value);
164
- }
165
- }
166
- finally {
167
- try {
168
- reader.releaseLock();
169
- }
170
- catch { /* may already be released */ }
171
- }
172
- return Buffer.concat(chunks);
173
- }
174
- /**
175
- * Fetch a URL, re-validating every hop against `isPrivateUrl`.
176
- *
177
- * The caller owns the deadline via `options.signal`, so the abort timeout
178
- * spans connect + redirects + body read (the body is consumed by the caller
179
- * after this returns) — a slow-trickle upstream that streams headers fast
180
- * but withholds the body can no longer hold the worker past the timeout.
181
- */
182
- async function fetchWithRedirectValidation(url, options = {}) {
183
- const accept = options.accept ?? 'text/html,application/xhtml+xml';
184
- const userAgent = options.userAgent ?? 'CommonPub/1.0 (+https://commonpub.io)';
185
- const signal = options.signal;
186
- let currentUrl = url;
187
- let redirectCount = 0;
188
- while (redirectCount < MAX_REDIRECTS) {
189
- if (isPrivateUrl(currentUrl)) {
190
- throw new Error('URL points to a private or reserved address');
191
- }
192
- const response = await fetch(currentUrl, {
193
- signal,
194
- redirect: 'manual',
195
- headers: { 'User-Agent': userAgent, 'Accept': accept },
196
- });
197
- if (response.status >= 300 && response.status < 400) {
198
- const location = response.headers.get('location');
199
- if (!location)
200
- throw new Error('Redirect without Location header');
201
- currentUrl = new URL(location, currentUrl).toString();
202
- redirectCount++;
203
- continue;
204
- }
205
- if (!response.ok) {
206
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
207
- }
208
- return { response, finalUrl: currentUrl };
209
- }
210
- throw new Error('Too many redirects');
211
- }
212
- /** Run an operation under a single abort deadline that spans fetch + body read. */
213
- async function withDeadline(timeoutMs, fn) {
214
- const controller = new AbortController();
215
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
216
- try {
217
- return await fn(controller.signal);
218
- }
219
- finally {
220
- clearTimeout(timeout);
221
- }
222
- }
223
- /**
224
- * Fetch a URL with SSRF protection, redirect re-validation, a streaming
225
- * size cap, and a deadline covering the whole exchange (incl. body read).
226
- * Returns the response body as a string.
227
- */
228
- export async function safeFetch(url, options = {}) {
229
- return withDeadline(options.timeoutMs ?? FETCH_TIMEOUT_MS, async (signal) => {
230
- const { response, finalUrl } = await fetchWithRedirectValidation(url, { ...options, signal });
231
- const buffer = await streamBoundedBody(response, MAX_RESPONSE_SIZE);
232
- return { html: new TextDecoder().decode(buffer), finalUrl };
233
- });
234
- }
235
- /**
236
- * Like `safeFetch` but returns the body as a Buffer plus the upstream
237
- * Content-Type. Use for binary content (images, etc.).
238
- */
239
- export async function safeFetchBinary(url, options = {}) {
240
- return withDeadline(options.timeoutMs ?? FETCH_TIMEOUT_MS, async (signal) => {
241
- const { response, finalUrl } = await fetchWithRedirectValidation(url, { ...options, signal });
242
- const contentType = response.headers.get('content-type') ?? '';
243
- const buffer = await streamBoundedBody(response, MAX_RESPONSE_SIZE);
244
- return { buffer, contentType, finalUrl };
245
- });
246
- }
4
+ * The canonical implementation moved to `@commonpub/protocol` in the
5
+ * federation-hardening work (Item 5) so `actorResolver` and the server
6
+ * share one module (and one pinned-lookup dispatcher). This shim keeps
7
+ * every internal `~/import/ssrf` import site and `@commonpub/server`'s
8
+ * public API (stable since 2.48.0) unchanged. Do not add logic here —
9
+ * edit `packages/protocol/src/ssrf.ts`.
10
+ */
11
+ export { isPrivateIp, isPrivateUrl, safeFetch, safeFetchBinary } from '@commonpub/protocol';
247
12
  //# sourceMappingURL=ssrf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/import/ssrf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/import/ssrf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commonpub/server",
3
- "version": "2.53.1",
3
+ "version": "2.54.0",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic business logic for CommonPub instances",
6
6
  "license": "AGPL-3.0-or-later",
@@ -108,14 +108,14 @@
108
108
  "linkedom": "^0.18.12",
109
109
  "megalodon": "^10.3.0",
110
110
  "turndown": "^7.2.4",
111
- "@commonpub/config": "0.12.0",
112
- "@commonpub/docs": "0.6.3",
111
+ "@commonpub/auth": "0.6.0",
112
+ "@commonpub/editor": "0.7.9",
113
+ "@commonpub/infra": "0.7.0",
113
114
  "@commonpub/learning": "0.5.2",
114
- "@commonpub/protocol": "0.9.10",
115
+ "@commonpub/config": "0.13.0",
116
+ "@commonpub/protocol": "0.10.0",
115
117
  "@commonpub/schema": "0.16.0",
116
- "@commonpub/infra": "0.7.0",
117
- "@commonpub/auth": "0.6.0",
118
- "@commonpub/editor": "0.7.9"
118
+ "@commonpub/docs": "0.6.3"
119
119
  },
120
120
  "peerDependencies": {
121
121
  "drizzle-orm": "^0.45.1"