fix: enforce API request limits

Add a single platform-owned request-body policy (hono/body-limit) with
small, named limits for Better Auth and Core's grant-mutation endpoint, and
a new required maxBodyBytes field on the executable module route contract so
every module route makes a conscious no-body-or-bounded-body choice, capped
at a platform ceiling. Every oversized request gets one sanitized 413
contract and never reaches business logic, authorization, or a handler.
Also configure finite Node header/request/keep-alive timeouts, including the
non-obvious connectionsCheckingInterval needed for them to take effect
promptly, so a slow-header or slow-body connection cannot hold a socket
indefinitely.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
ekklesia
2026-07-26 12:29:24 -05:00
co-authored by Claude Sonnet 5
parent cafd513019
commit d3c6bd73d3
24 changed files with 1419 additions and 96 deletions
+3 -1
View File
@@ -12,6 +12,7 @@ import { type EkklesiaIdentityRuntime, IdentityRuntimeError } from "@ekklesia/co
import { Hono } from "hono";
import type { Context, MiddlewareHandler } from "hono";
import { cors } from "hono/cors";
import { AUTH_REQUEST_MAX_BODY_BYTES, platformBodyLimit } from "./body-limits.js";
import { createGrantsRoutes } from "./grants-routes.js";
import { canonicalizeVaryHeader, mountModuleHttpRoutes } from "./module-http-routes.js";
@@ -117,7 +118,8 @@ export function createApiApp(options: CreateApiAppOptions): Hono {
app.use("/api/auth/*", corsMiddleware);
app.use("/api/v1/*", corsMiddleware);
app.on(["POST", "GET"], "/api/auth/*", async (c) => {
const authBodyLimit = platformBodyLimit(AUTH_REQUEST_MAX_BODY_BYTES);
app.on(["POST", "GET"], "/api/auth/*", authBodyLimit, async (c) => {
try {
const response = await runtime.handleAuthRequest(c.req.raw);
// Every Better Auth response — including a session cookie — must never be cached by an