@rapidrest/service-core 2.2.0 → 2.3.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.
package/README.md CHANGED
@@ -40,6 +40,8 @@ For complete documentation please visit [RapidREST.dev](https://rapidrest.dev).
40
40
  - Server-side session management (in-memory or Redis-backed)
41
41
  - Attempt-count rate limiting (`RateLimiter`) for brute-force/abuse defense, layered per-identifier
42
42
  and per-source-IP (reverse-proxy aware), Redis-backed and atomic across instances
43
+ - CSRF (double-submit cookie) protection (`RouteUtils.checkCsrf()`), applied automatically to every
44
+ cookie-authenticated, state-changing request — never a bearer-token/API-key/query-token caller
43
45
 
44
46
  **Real-time & Background Work**
45
47
 
@@ -24,11 +24,13 @@ export var ApiErrors;
24
24
  ApiErrors["SEARCH_OPERATOR_NOT_SUPPORTED"] = "api-020";
25
25
  ApiErrors["BULK_CREATE_FAILURE"] = "api-021";
26
26
  ApiErrors["BULK_UPDATE_FAILURE"] = "api-022";
27
+ ApiErrors["SEARCH_SCOPED_FIELD"] = "api-023";
27
28
  ApiErrors["AUTH_REQUIRED"] = "api-100";
28
29
  ApiErrors["AUTH_FAILED"] = "api-101";
29
30
  ApiErrors["AUTH_PERMISSION_FAILURE"] = "api-102";
30
31
  ApiErrors["AUTH_REQUIRES_TRUSTED_ROLE"] = "api-103";
31
32
  ApiErrors["AUTH_REQUIRES_ELEVATION"] = "api-104";
33
+ ApiErrors["AUTH_CSRF_FAILURE"] = "api-105";
32
34
  })(ApiErrors || (ApiErrors = {}));
33
35
  /**
34
36
  * Defines the default message of all common API errors.
@@ -52,10 +54,12 @@ export var ApiErrorMessages;
52
54
  ApiErrorMessages["SEARCH_OPERATOR_NOT_SUPPORTED"] = "The '{{operator}}' operator is not supported by the configured datasource.";
53
55
  ApiErrorMessages["BULK_CREATE_FAILURE"] = "Failed to create one or more objects.";
54
56
  ApiErrorMessages["BULK_UPDATE_FAILURE"] = "Failed to update one or more objects.";
57
+ ApiErrorMessages["SEARCH_SCOPED_FIELD"] = "Cannot filter, sort or count by scoped field '{{field}}'.";
55
58
  ApiErrorMessages["AUTH_REQUIRED"] = "Authorization is required to access this resource.";
56
59
  ApiErrorMessages["AUTH_FAILED"] = "Invalid or missing authentication token.";
57
60
  ApiErrorMessages["AUTH_PERMISSION_FAILURE"] = "User does not have permission to perform this action.";
58
61
  ApiErrorMessages["AUTH_REQUIRES_TRUSTED_ROLE"] = "User does not have permission to perform this action.";
59
62
  ApiErrorMessages["AUTH_REQUIRES_ELEVATION"] = "This operation requires elevation.";
63
+ ApiErrorMessages["AUTH_CSRF_FAILURE"] = "This request is missing a valid CSRF token.";
60
64
  })(ApiErrorMessages || (ApiErrorMessages = {}));
61
65
  //# sourceMappingURL=ApiErrors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApiErrors.js","sourceRoot":"","sources":["../../src/ApiErrors.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,mCAAmC;AACnC,+EAA+E;AAC/E;;GAEG;AACH,MAAM,CAAN,IAAY,SAuBX;AAvBD,WAAY,SAAS;IACjB,gCAAmB,CAAA;IACnB,uCAA0B,CAAA;IAC1B,wCAA2B,CAAA;IAC3B,0CAA6B,CAAA;IAC7B,kCAAqB,CAAA;IACrB,0CAA6B,CAAA;IAC7B,+CAAkC,CAAA;IAClC,2CAA8B,CAAA;IAC9B,6CAAgC,CAAA;IAChC,oDAAuC,CAAA;IACvC,gDAAmC,CAAA;IACnC,oDAAuC,CAAA;IACvC,kDAAqC,CAAA;IACrC,iDAAoC,CAAA;IACpC,sDAAyC,CAAA;IACzC,4CAA+B,CAAA;IAC/B,4CAA+B,CAAA;IAC/B,sCAAyB,CAAA;IACzB,oCAAuB,CAAA;IACvB,gDAAmC,CAAA;IACnC,mDAAsC,CAAA;IACtC,gDAAmC,CAAA;AACvC,CAAC,EAvBW,SAAS,KAAT,SAAS,QAuBpB;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAuBX;AAvBD,WAAY,gBAAgB;IACxB,gFAA4D,CAAA;IAC5D,uGAAmF,CAAA;IACnF,mEAA+C,CAAA;IAC/C,4FAAwE,CAAA;IACxE,2FAAuE,CAAA;IACvE,yFAAqE,CAAA;IACrE,sGAAkF,CAAA;IAClF,mGAA+E,CAAA;IAC/E,mHAA+F,CAAA;IAC/F,sGAAkF,CAAA;IAClF,4JAAwI,CAAA;IACxI,yHAAqG,CAAA;IACrG,2FAAuE,CAAA;IACvE,kHAA8F,CAAA;IAC9F,gIAA4G,CAAA;IAC5G,iFAA6D,CAAA;IAC7D,iFAA6D,CAAA;IAC7D,wFAAoE,CAAA;IACpE,4EAAwD,CAAA;IACxD,qGAAiF,CAAA;IACjF,wGAAoF,CAAA;IACpF,kFAA8D,CAAA;AAClE,CAAC,EAvBW,gBAAgB,KAAhB,gBAAgB,QAuB3B"}
1
+ {"version":3,"file":"ApiErrors.js","sourceRoot":"","sources":["../../src/ApiErrors.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,mCAAmC;AACnC,+EAA+E;AAC/E;;GAEG;AACH,MAAM,CAAN,IAAY,SAyBX;AAzBD,WAAY,SAAS;IACjB,gCAAmB,CAAA;IACnB,uCAA0B,CAAA;IAC1B,wCAA2B,CAAA;IAC3B,0CAA6B,CAAA;IAC7B,kCAAqB,CAAA;IACrB,0CAA6B,CAAA;IAC7B,+CAAkC,CAAA;IAClC,2CAA8B,CAAA;IAC9B,6CAAgC,CAAA;IAChC,oDAAuC,CAAA;IACvC,gDAAmC,CAAA;IACnC,oDAAuC,CAAA;IACvC,kDAAqC,CAAA;IACrC,iDAAoC,CAAA;IACpC,sDAAyC,CAAA;IACzC,4CAA+B,CAAA;IAC/B,4CAA+B,CAAA;IAC/B,4CAA+B,CAAA;IAC/B,sCAAyB,CAAA;IACzB,oCAAuB,CAAA;IACvB,gDAAmC,CAAA;IACnC,mDAAsC,CAAA;IACtC,gDAAmC,CAAA;IACnC,0CAA6B,CAAA;AACjC,CAAC,EAzBW,SAAS,KAAT,SAAS,QAyBpB;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAyBX;AAzBD,WAAY,gBAAgB;IACxB,gFAA4D,CAAA;IAC5D,uGAAmF,CAAA;IACnF,mEAA+C,CAAA;IAC/C,4FAAwE,CAAA;IACxE,2FAAuE,CAAA;IACvE,yFAAqE,CAAA;IACrE,sGAAkF,CAAA;IAClF,mGAA+E,CAAA;IAC/E,mHAA+F,CAAA;IAC/F,sGAAkF,CAAA;IAClF,4JAAwI,CAAA;IACxI,yHAAqG,CAAA;IACrG,2FAAuE,CAAA;IACvE,kHAA8F,CAAA;IAC9F,gIAA4G,CAAA;IAC5G,iFAA6D,CAAA;IAC7D,iFAA6D,CAAA;IAC7D,qGAAiF,CAAA;IACjF,wFAAoE,CAAA;IACpE,4EAAwD,CAAA;IACxD,qGAAiF,CAAA;IACjF,wGAAoF,CAAA;IACpF,kFAA8D,CAAA;IAC9D,qFAAiE,CAAA;AACrE,CAAC,EAzBW,gBAAgB,KAAhB,gBAAgB,QAyB3B"}
@@ -89,7 +89,7 @@ export class JWTStrategy {
89
89
  /**
90
90
  * Scans the provided request object for an authentication token this strategy can process.
91
91
  * @param req The request to scan for an auth token.
92
- * @returns The auth token if found, otherwise `undefined`.
92
+ * @returns The auth token and which source it was found in, if found, otherwise `undefined`.
93
93
  */
94
94
  getAuthToken(req) {
95
95
  let authToken = undefined;
@@ -100,6 +100,9 @@ export class JWTStrategy {
100
100
  req.query &&
101
101
  this.options.queryKey in req.query) {
102
102
  authToken = req.query[this.options.queryKey];
103
+ if (authToken) {
104
+ return { token: authToken, source: "query" };
105
+ }
103
106
  }
104
107
  // Next check the headers, but only if a higher-precedence source (the query parameter above)
105
108
  // hasn't already supplied a token — a later-checked, lower-precedence source must never override
@@ -120,6 +123,9 @@ export class JWTStrategy {
120
123
  authToken = parts[1];
121
124
  break;
122
125
  }
126
+ if (authToken) {
127
+ return { token: authToken, source: "header" };
128
+ }
123
129
  }
124
130
  // Check the cookie header — lowest precedence, so only consulted if neither the query parameter
125
131
  // nor the header supplied a token above.
@@ -129,21 +135,22 @@ export class JWTStrategy {
129
135
  if (!authToken && this.options.cookieSecure && this.options.cookieName && req.signedCookies) {
130
136
  const cookieToken = req.signedCookies[this.options.cookieName];
131
137
  if (cookieToken) {
132
- authToken = cookieToken;
138
+ return { token: cookieToken, source: "cookie" };
133
139
  }
134
140
  }
135
141
  if (!authToken && !this.options.cookieSecure && this.options.cookieName && req.cookies) {
136
142
  const cookieToken = req.cookies[this.options.cookieName];
137
143
  if (cookieToken) {
138
- authToken = cookieToken;
144
+ return { token: cookieToken, source: "cookie" };
139
145
  }
140
146
  }
141
- return authToken;
147
+ return undefined;
142
148
  }
143
149
  async authenticate(req, res) {
144
150
  let user = undefined;
145
151
  let authPayload = undefined;
146
- let authToken = this.getAuthToken(req);
152
+ const found = this.getAuthToken(req);
153
+ const authToken = found?.token;
147
154
  // If the token has been found, verify it.
148
155
  if (authToken && authToken.length > 0) {
149
156
  const payload = await JWTUtils.decodeToken(this.config, authToken);
@@ -168,6 +175,7 @@ export class JWTStrategy {
168
175
  method: this.name,
169
176
  payload: authPayload,
170
177
  tokenFound: authToken !== undefined,
178
+ source: found?.source,
171
179
  user,
172
180
  };
173
181
  }
@@ -177,7 +185,8 @@ export class JWTStrategy {
177
185
  authenticateSync(req, res) {
178
186
  let user = undefined;
179
187
  let authPayload = undefined;
180
- let authToken = this.getAuthToken(req);
188
+ const found = this.getAuthToken(req);
189
+ const authToken = found?.token;
181
190
  // If the token has been found, verify it.
182
191
  if (authToken && authToken.length > 0) {
183
192
  const payload = JWTUtils.decodeTokenSync(this.config, authToken);
@@ -202,6 +211,7 @@ export class JWTStrategy {
202
211
  method: this.name,
203
212
  payload: authPayload,
204
213
  tokenFound: authToken !== undefined,
214
+ source: found?.source,
205
215
  user,
206
216
  };
207
217
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JWTStrategy.js","sourceRoot":"","sources":["../../../src/auth/JWTStrategy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"JWTStrategy.js","sourceRoot":"","sources":["../../../src/auth/JWTStrategy.ts"],"names":[],"mappings":"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"}
@@ -338,11 +338,19 @@ export async function readBunBody(req, rawRequest, maxBodySize = DEFAULT_MAX_BOD
338
338
  * Destroys the returned stream if the client disconnects mid-upload, via the request's own
339
339
  * `AbortSignal` — mirroring `makeBodyStream()`'s uWS `onAborted`-driven cleanup — so a handler
340
340
  * consuming it via `for await` sees a thrown error instead of hanging forever.
341
+ *
342
+ * A route that never reads the returned stream at all can still trigger that destroy() (the request
343
+ * simply gets aborted independently, e.g. the client navigating away), so a permanent no-op `error`
344
+ * listener is attached — a `Readable` with no active consumer still emits `error` on `destroy(err)`,
345
+ * and Node treats a zero-listener `error` event as fatal (crashes the process). This doesn't swallow
346
+ * anything from a real consumer: EventEmitter calls every registered listener, not just the first, so
347
+ * `for await`/`.pipe()`/an explicit `.on("error")` still see the same event independently.
341
348
  */
342
349
  export function makeBunBodyStream(rawRequest) {
343
350
  if (!rawRequest.body)
344
351
  return undefined;
345
352
  const stream = Readable.fromWeb(rawRequest.body);
353
+ stream.on("error", () => undefined);
346
354
  rawRequest.signal?.addEventListener("abort", () => {
347
355
  if (!stream.destroyed) {
348
356
  stream.destroy(new Error("Request aborted before the body stream was fully read."));
@@ -1 +1 @@
1
- {"version":3,"file":"BunAdapters.js","sourceRoot":"","sources":["../../../../src/http/bun/BunAdapters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BunAdapters.js","sourceRoot":"","sources":["../../../../src/http/bun/BunAdapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,212 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import * as crypto from "crypto";
6
+ import { ApiError } from "@rapidrest/core";
7
+ import { ApiErrorMessages, ApiErrors } from "../../ApiErrors.js";
8
+ /**
9
+ * Double-submit CSRF protection for the `jwt` cookie that `@rapidrest/auth`'s `TokenUtils` issues (see
10
+ * that library's `CsrfUtils`, which rotates this same cookie at login/elevation/logout). This module is
11
+ * the shared, framework-agnostic core: `RouteUtils.checkCsrf()` wires it into every route's middleware
12
+ * chain automatically, and `createCsrfMiddleware()` below offers the same check as a standalone global
13
+ * middleware for a service that doesn't go through `RouteUtils` (or wants it registered once instead of
14
+ * per-route). `auth`'s route handlers that read `req.session` directly instead of going through the
15
+ * `jwt`-cookie auth path (e.g. the OAuth `/authorize/consent` route) call `verifyCsrfRequest()` by hand —
16
+ * see that route's own doc comment for why it can't rely on the automatic, `req.auth`-keyed gate.
17
+ *
18
+ * ## Why this is a host-only cookie, not a naive double-submit
19
+ *
20
+ * The `jwt`/`refresh` cookies `TokenUtils` issues are commonly configured with a wildcard `Domain`
21
+ * (e.g. `.example.com`) so a single sign-in is shared across sibling subdomains (`mail.example.com`,
22
+ * `auth.example.com`, ...) — that's the whole point of a shared SSO cookie. A *naive* double-submit CSRF
23
+ * cookie sharing that same wildcard `Domain` would defeat itself: `document.cookie` on *any* sibling
24
+ * subdomain can read a wildcard-domain cookie, so a same-site page that isn't the app itself (a
25
+ * compromised or merely less-trusted subdomain, a multi-tenant customer subdomain, ...) could read the
26
+ * "secret" double-submit value and echo it right back — exactly the value this scheme exists to keep
27
+ * out of an attacker's hands. `SameSite=Lax` doesn't help here either: it blocks genuine cross-*site*
28
+ * forgery, but `auth.example.com` and `mail.example.com` are cross-*origin*, same-*site* — Lax cookies
29
+ * are still attached.
30
+ *
31
+ * `buildCsrfCookie()` below therefore never emits a `Domain` attribute: the cookie this module issues is
32
+ * always host-only, readable only by script running on the exact host that set it. That closes the
33
+ * sibling-subdomain-reads-the-cookie hole, but it also means a *legitimately* cross-origin caller (e.g.
34
+ * `react-shared`'s `authApiFetch()`, used by an admin console on `mail.example.com` to drive
35
+ * impersonation on `auth.example.com`) can never read this cookie either — there is no way for it to
36
+ * supply a matching header. `verifyCsrfRequest()` handles that case by falling back to an Origin/Referer
37
+ * allow-list check for any request whose Origin doesn't match the host it arrived on: the browser only
38
+ * ever sends such a request in the first place because the target's CORS policy already named that exact
39
+ * origin as trusted (see `Server.ts`'s CORS middleware, which reflects `Access-Control-Allow-Origin` only
40
+ * for an exact, explicitly configured match — never a wildcard-with-credentials), so re-checking the same
41
+ * allow-list server-side is a legitimate, independent proof for a cross-origin request in a way that
42
+ * would not exist for a same-origin one.
43
+ */
44
+ /** Default name of the double-submit CSRF cookie. */
45
+ export const DEFAULT_CSRF_COOKIE_NAME = "csrf";
46
+ /** Default name of the request header a caller echoes the CSRF cookie's value back on. */
47
+ export const DEFAULT_CSRF_HEADER_NAME = "x-csrf-token";
48
+ /** HTTP methods exempt from CSRF checks — by definition never supposed to mutate state. */
49
+ const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
50
+ /** Generates a new, cryptographically random CSRF token, matching `OIDCStrategy`'s own `state`-token style. */
51
+ export function generateCsrfToken() {
52
+ return crypto.randomBytes(32).toString("base64url");
53
+ }
54
+ /**
55
+ * Builds the `Set-Cookie` header value for the CSRF cookie. Pass an empty string for `token` to build a
56
+ * header that immediately clears the cookie instead (mirrors `TokenUtils.buildCookie()`'s own clearing
57
+ * convention in `@rapidrest/auth`).
58
+ *
59
+ * Deliberately never emits a `Domain` attribute, even though the sibling `jwt`/`refresh` cookies often do
60
+ * — see this module's doc comment for why a wide-open `Domain` here would defeat the whole scheme.
61
+ * Deliberately never emits `HttpOnly` either: browser JavaScript reading this cookie and echoing it back
62
+ * as a header is the entire mechanism.
63
+ */
64
+ export function buildCsrfCookie(token, options = {}) {
65
+ const clearing = token === "";
66
+ const parts = [`${options.name ?? DEFAULT_CSRF_COOKIE_NAME}=${token}`, `Path=${options.path ?? "/"}`];
67
+ parts.push(`SameSite=${options.sameSite ?? "Lax"}`);
68
+ if (clearing) {
69
+ parts.push("Max-Age=0");
70
+ }
71
+ else if (options.maxAge !== undefined) {
72
+ parts.push(`Max-Age=${options.maxAge}`);
73
+ }
74
+ if (options.secure !== false) {
75
+ parts.push("Secure");
76
+ }
77
+ return parts.join("; ");
78
+ }
79
+ /** Constant-time string comparison. Rejects a length mismatch up front — `crypto.timingSafeEqual()` throws on one
80
+ * rather than returning `false`, and comparing lengths first is itself safe (a token's length isn't a secret). */
81
+ function timingSafeEqualStr(a, b) {
82
+ const bufA = Buffer.from(a);
83
+ const bufB = Buffer.from(b);
84
+ return bufA.length > 0 && bufA.length === bufB.length && crypto.timingSafeEqual(bufA, bufB);
85
+ }
86
+ function firstHeaderValue(value) {
87
+ return Array.isArray(value) ? value[0] : value;
88
+ }
89
+ /** Extracts `scheme://host` from a full URL string (e.g. a `Referer` header), or `undefined` if unparseable. */
90
+ function originOf(url) {
91
+ if (!url) {
92
+ return undefined;
93
+ }
94
+ try {
95
+ const parsed = new URL(url);
96
+ return `${parsed.protocol}//${parsed.host}`;
97
+ }
98
+ catch {
99
+ return undefined;
100
+ }
101
+ }
102
+ /** Extracts just the `host` (hostname[:port], no scheme) portion of an origin string, or `undefined` if unparseable. */
103
+ function hostOf(origin) {
104
+ if (!origin) {
105
+ return undefined;
106
+ }
107
+ try {
108
+ return new URL(origin).host;
109
+ }
110
+ catch {
111
+ return undefined;
112
+ }
113
+ }
114
+ /**
115
+ * Ensures the caller holds a CSRF cookie, issuing one via `Set-Cookie` if it doesn't already have a valid
116
+ * one — the standard "set on first visit" double-submit pattern (matches Django/Rails), and what lets a
117
+ * service that never itself issues auth cookies (e.g. `server`/`restapi`, which only ever verify a `jwt`
118
+ * cookie someone else set) still adopt this mechanism on its own. Returns the (possibly freshly-generated)
119
+ * token value.
120
+ */
121
+ export function ensureCsrfCookie(req, res, options = {}) {
122
+ const cookieName = options.cookieName ?? DEFAULT_CSRF_COOKIE_NAME;
123
+ const existing = req.cookies?.[cookieName];
124
+ if (existing) {
125
+ return existing;
126
+ }
127
+ const token = generateCsrfToken();
128
+ res.appendHeader("Set-Cookie", buildCsrfCookie(token, { name: cookieName, maxAge: options.maxAge, secure: options.secure }));
129
+ return token;
130
+ }
131
+ /**
132
+ * Verifies `req` against the double-submit CSRF cookie plus Origin/Referer allow-list, per the scheme
133
+ * documented at the top of this module. Throws an `ApiError` (`AUTH_CSRF_FAILURE`, 403) on failure. A safe
134
+ * method (`GET`/`HEAD`/`OPTIONS`) or `options.enabled === false` always passes without throwing.
135
+ *
136
+ * This does *not* check `req.auth?.source` — that gate belongs to the caller (see `RouteUtils.checkCsrf()`,
137
+ * which only calls this when `req.auth?.source === "cookie"`). A caller like `BaseOAuthAuthorizeRoute`'s
138
+ * `decideConsent()`, which authenticates via `req.session` instead of a JWT, calls this unconditionally
139
+ * for exactly that reason.
140
+ */
141
+ export function verifyCsrfRequest(req, options = {}) {
142
+ if (options.enabled === false) {
143
+ return;
144
+ }
145
+ const method = (req.method || "GET").toUpperCase();
146
+ if (SAFE_METHODS.has(method)) {
147
+ return;
148
+ }
149
+ const cookieName = options.cookieName ?? DEFAULT_CSRF_COOKIE_NAME;
150
+ const headerName = (options.headerName ?? DEFAULT_CSRF_HEADER_NAME).toLowerCase();
151
+ const allowedOrigins = options.allowedOrigins ?? [];
152
+ const originHeader = firstHeaderValue(req.headers["origin"]);
153
+ const refererHeader = firstHeaderValue(req.headers["referer"] ?? req.headers["referrer"]);
154
+ const effectiveOrigin = originHeader ?? originOf(refererHeader);
155
+ const hostHeader = firstHeaderValue(req.headers["host"]);
156
+ const originHost = hostOf(effectiveOrigin);
157
+ // Scheme is deliberately not part of this comparison: a TLS-terminating proxy commonly forwards a
158
+ // plain-HTTP request to this process for an origin the browser saw as `https://`, and that mismatch
159
+ // alone must never be treated as cross-origin.
160
+ const crossOrigin = !!originHost && !!hostHeader && originHost !== hostHeader;
161
+ // Defense in depth, checked regardless of same/cross-origin whenever an Origin (or Referer fallback)
162
+ // is present and an allow-list is configured: a same-origin request forging its own Origin header is
163
+ // not something a browser lets a page do, so this mainly guards against a misconfigured proxy or a
164
+ // non-browser replay of a stolen cookie pair.
165
+ if (effectiveOrigin && allowedOrigins.length > 0 && !allowedOrigins.includes(effectiveOrigin)) {
166
+ options.logger?.warn?.(`[CSRF] Rejected ${method} ${req.path} — origin '${effectiveOrigin}' is not allow-listed.`);
167
+ throw new ApiError(ApiErrors.AUTH_CSRF_FAILURE, 403, ApiErrorMessages.AUTH_CSRF_FAILURE);
168
+ }
169
+ if (crossOrigin) {
170
+ // A cross-origin caller's own JavaScript cannot read this host's host-only CSRF cookie (see this
171
+ // module's doc comment), so the double-submit check below is structurally unsatisfiable for it —
172
+ // the Origin allow-list check above is this request's only available CSRF defense. Fail closed if
173
+ // there's no allow-list configured at all: nothing here proved the request legitimate.
174
+ if (allowedOrigins.length === 0) {
175
+ options.logger?.warn?.(`[CSRF] Rejected cross-origin ${method} ${req.path} — no CSRF allow-list configured.`);
176
+ throw new ApiError(ApiErrors.AUTH_CSRF_FAILURE, 403, ApiErrorMessages.AUTH_CSRF_FAILURE);
177
+ }
178
+ return;
179
+ }
180
+ const cookieToken = req.cookies?.[cookieName];
181
+ const headerToken = firstHeaderValue(req.headers[headerName]);
182
+ if (!cookieToken || !headerToken || !timingSafeEqualStr(cookieToken, headerToken)) {
183
+ options.logger?.warn?.(`[CSRF] Rejected ${method} ${req.path} — missing or mismatched '${headerName}' header.`);
184
+ throw new ApiError(ApiErrors.AUTH_CSRF_FAILURE, 403, ApiErrorMessages.AUTH_CSRF_FAILURE);
185
+ }
186
+ }
187
+ /**
188
+ * Standalone global-middleware form of the same check `RouteUtils.checkCsrf()` installs automatically on
189
+ * every route. Useful for a service that registers its own middleware chain directly instead of going
190
+ * through `RouteUtils` (or that wants a single global registration instead of a per-route one). Always
191
+ * lazily issues the cookie first (see `ensureCsrfCookie()`), then enforces the check only when
192
+ * `req.auth?.source === "cookie"` — the same gate `RouteUtils.checkCsrf()` uses.
193
+ */
194
+ export function createCsrfMiddleware(options = {}) {
195
+ return (req, res, next) => {
196
+ if (options.enabled !== false) {
197
+ ensureCsrfCookie(req, res, options);
198
+ }
199
+ if (req.auth?.source !== "cookie") {
200
+ next();
201
+ return;
202
+ }
203
+ try {
204
+ verifyCsrfRequest(req, options);
205
+ next();
206
+ }
207
+ catch (err) {
208
+ next(err);
209
+ }
210
+ };
211
+ }
212
+ //# sourceMappingURL=csrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../../../src/http/csrf/csrf.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,12 @@ export { extractParamNames, makeWsStubResponse, runChain, splitRouteArgs } from
4
4
  export { RedisSessionStore } from "./session/RedisSessionStore.js";
5
5
  export { SessionManager } from "./session/SessionManager.js";
6
6
  export { createSessionMiddleware } from "./session/sessionMiddleware.js";
7
+ // CSRF support — double-submit cookie protection for the `jwt` cookie `@rapidrest/auth`'s `TokenUtils`
8
+ // issues. `RouteUtils.checkCsrf()` wires the check into every registered route automatically; the pieces
9
+ // below are exported for a route that must check by hand (session-only auth, not the `jwt` cookie — see
10
+ // `BaseOAuthAuthorizeRoute.decideConsent()` in `@rapidrest/auth`) or a service that registers its own
11
+ // middleware chain outside of `RouteUtils`.
12
+ export { DEFAULT_CSRF_COOKIE_NAME, DEFAULT_CSRF_HEADER_NAME, buildCsrfCookie, createCsrfMiddleware, ensureCsrfCookie, generateCsrfToken, verifyCsrfRequest, } from "./csrf/csrf.js";
7
13
  // uWS-backed adapter. `HttpRouter` is exported as a type only — the class itself value-imports
8
14
  // `uWebSockets.js` at module load, which does not work under Bun. Consumers that only annotate with
9
15
  // the type stay safe on every runtime; constructing one is done internally by Server.ts via a
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/http/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,+FAA+F;AAC/F,oGAAoG;AACpG,8FAA8F;AAC9F,4CAA4C;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGtF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,kGAAkG;AAClG,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/http/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,uGAAuG;AACvG,yGAAyG;AACzG,wGAAwG;AACxG,sGAAsG;AACtG,4CAA4C;AAC5C,OAAO,EACH,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,+FAA+F;AAC/F,oGAAoG;AACpG,8FAA8F;AAC9F,4CAA4C;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGtF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,kGAAkG;AAClG,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -166,6 +166,16 @@ export class UWSResponse {
166
166
  this._fireFinish();
167
167
  });
168
168
  }
169
+ /**
170
+ * Associates this response with a streaming-body route's `req.bodyStream`, so `end()` can detect
171
+ * a response finalizing before uWS has received the whole declared request body and force the
172
+ * connection closed instead of hanging it — see `isBodyStreamFullyReceived()`'s doc comment for
173
+ * the full rationale. Called once, by the router, right after `makeBodyStream()` creates the
174
+ * stream (`HttpRouteOptions.streamingBody` routes only — never called otherwise).
175
+ */
176
+ attachBodyStream(stream) {
177
+ this._bodyStream = stream;
178
+ }
169
179
  get statusCode() {
170
180
  return this._statusCode;
171
181
  }
@@ -220,6 +230,27 @@ export class UWSResponse {
220
230
  return;
221
231
  this._writableEnded = true;
222
232
  this._fireFinish();
233
+ if (this._bodyStream && !isBodyStreamFullyReceived(this._bodyStream)) {
234
+ // This is a streaming-body route finalizing its response before uWS has received the
235
+ // whole declared request body — whether because the handler responded without draining
236
+ // req.bodyStream (an auth/validation failure, typically), a slow-but-legitimate client
237
+ // hasn't finished sending yet, or (the exploit this specifically defends against) the
238
+ // client declared a huge Content-Length and never intends to send it. A graceful
239
+ // uwsRes.end() here would leave the connection sitting in uWS's keep-alive machinery
240
+ // waiting for bytes that may never arrive — indefinitely, for the cost of a single
241
+ // request's worth of headers. Force the connection closed instead: uWS won't accept
242
+ // further writes/reads on it either way once this response is finalizing, so there's
243
+ // nothing lost by not attempting a graceful end() here that keep-alive could have reused.
244
+ // uwsRes.close() also fires the onAborted callback already registered in the constructor,
245
+ // which destroys req.bodyStream (via makeBodyStream()'s res.onAbort() hookup) for us.
246
+ try {
247
+ this.uwsRes.close();
248
+ }
249
+ catch {
250
+ // Already invalid/closed — nothing left to do.
251
+ }
252
+ return;
253
+ }
223
254
  this.uwsRes.cork(() => {
224
255
  // Write status line (uWS expects "200 OK" format)
225
256
  if (!this._headersSent) {
@@ -447,6 +478,36 @@ export function readBody(uwsRes, req, maxBodySize = DEFAULT_MAX_BODY_SIZE, res)
447
478
  * plenty of headroom before the network is throttled.
448
479
  */
449
480
  export const STREAMING_BODY_HIGH_WATER_MARK = 1024 * 1024;
481
+ /**
482
+ * Internal marker set on every `Readable` returned by `makeBodyStream()`, tracking whether uWS has
483
+ * delivered the final chunk of the request body (`onData`'s `isLast`) yet. Deliberately independent
484
+ * of the stream's own `readableEnded` — Node only flips `readableEnded` once a consumer has actually
485
+ * read all the way to the end, so a stream nobody ever reads from (e.g. a route that rejects the
486
+ * request before touching `req.bodyStream` at all) would stay `readableEnded === false` forever even
487
+ * for a request with an already-fully-arrived, zero-byte body. `isBodyStreamFullyReceived()` reads
488
+ * this marker instead — see its own doc comment and `UWSResponse.end()`, which uses it to decide
489
+ * between a graceful `end()` and a forced `close()`.
490
+ */
491
+ const FULLY_RECEIVED = Symbol("uwsBodyStreamFullyReceived");
492
+ /**
493
+ * Returns `true` once uWS has delivered the final chunk of `stream`'s request body — i.e. it is safe
494
+ * to let the underlying connection return to uWS's keep-alive pool — regardless of whether anything
495
+ * has actually consumed the stream. Returns `true` for `undefined` (nothing to wait for) so callers
496
+ * can pass `req.bodyStream` directly without an existence check first.
497
+ *
498
+ * See `UWSResponse.end()`: a streaming route's handler can legitimately respond (an auth failure, a
499
+ * validation error, anything) without ever reading `req.bodyStream`. If the client declared a large
500
+ * `Content-Length` and hasn't actually sent it all yet — or, in the malicious case, never intends to
501
+ * — a plain `uwsRes.end()` at that point leaves the keep-alive connection open indefinitely: uWS
502
+ * won't consider it clean for reuse until it has received every byte of the declared body, and nothing
503
+ * in that scenario ever makes that happen. `end()` uses this check to force the connection closed
504
+ * instead whenever it would otherwise leave that promise unfulfilled.
505
+ */
506
+ export function isBodyStreamFullyReceived(stream) {
507
+ if (!stream)
508
+ return true;
509
+ return stream[FULLY_RECEIVED] === true;
510
+ }
450
511
  /**
451
512
  * Exposes a uWS request body as a Node `Readable` stream instead of buffering it into memory, for a
452
513
  * route registered with `{ streamingBody: true }` (see `HttpRouteOptions`). Does NOT populate
@@ -466,12 +527,23 @@ export const STREAMING_BODY_HIGH_WATER_MARK = 1024 * 1024;
466
527
  * pause/resume pairing uWS expects. A slow consumer (a route piping to a slow disk, or one simply
467
528
  * not reading yet) still throttles how fast bytes are pulled off the client connection rather than
468
529
  * piling up unbounded data in process memory — the failure mode this whole feature exists to avoid.
530
+ * The same pairing discipline also applies to the final chunk: when a chunk that overflows the
531
+ * buffer also happens to be the last one (`isLast`), `pause()` is skipped entirely — the stream is
532
+ * about to signal EOF via `push(null)` regardless, so Node's `Readable` never calls `_read()` again
533
+ * to issue the matching `resume()`, which would otherwise leave uWS's connection paused forever with
534
+ * nothing left in this function to ever un-pause it.
469
535
  *
470
536
  * The stream is destroyed with an error if the client disconnects mid-upload (wired through the
471
537
  * existing single `onAborted` fan-out via `res.onAbort()`, matching `readBody()`'s own abort
472
538
  * handling) so a handler awaiting `for await (const chunk of req.bodyStream)` sees a thrown error
473
539
  * instead of hanging forever, and can clean up (e.g. delete a partial temp file) in its own
474
- * `catch`/`finally`.
540
+ * `catch`/`finally`. A route that never reads `req.bodyStream` at all can still hit this path — e.g.
541
+ * `UWSResponse.end()` itself calls `uwsRes.close()` (which fires `onAborted`) when finalizing a
542
+ * response before the body was fully received — so a permanent no-op `error` listener is attached
543
+ * below as well: a `Readable` with no active consumer still emits `error` on `destroy(err)`, and
544
+ * Node treats an `error` event with zero listeners as fatal (crashes the process). This listener
545
+ * doesn't swallow anything from a real consumer — `for await`/`.pipe()`/an explicit `.on("error")`
546
+ * all still see the same event; EventEmitter calls every registered listener, not just the first.
475
547
  *
476
548
  * Must be called synchronously, before any `await`, in the same tick as request handling begins —
477
549
  * uWS requires `onData`/`onAborted` to be registered before any asynchronous operation, matching the
@@ -501,6 +573,11 @@ export function makeBodyStream(uwsRes, res) {
501
573
  callback(err);
502
574
  },
503
575
  });
576
+ stream[FULLY_RECEIVED] = false;
577
+ // Safety net against an unhandled 'error' event crashing the process when nobody ever consumes
578
+ // this stream — see the doc comment above for the full rationale. A real consumer (for await,
579
+ // .pipe(), or its own .on("error")) still observes the same event independently of this listener.
580
+ stream.on("error", () => undefined);
504
581
  res.onAbort(() => {
505
582
  if (stream.destroyed)
506
583
  return;
@@ -517,12 +594,15 @@ export function makeBodyStream(uwsRes, res) {
517
594
  // `chunk` is a raw ArrayBuffer uWS reuses/detaches once this callback returns — see the
518
595
  // identical, more detailed comment in readBody() above for why `.slice(0)` is required.
519
596
  const ok = stream.push(Buffer.from(chunk.slice(0)));
520
- if (!ok) {
597
+ // Never pause on the final chunk — see the doc comment above for why that would leave
598
+ // the connection paused with no matching resume() ever coming.
599
+ if (!ok && !isLast) {
521
600
  paused = true;
522
601
  uwsRes.pause();
523
602
  }
524
603
  }
525
604
  if (isLast) {
605
+ stream[FULLY_RECEIVED] = true;
526
606
  stream.push(null);
527
607
  }
528
608
  });