Fix security vulnerabilities and request handling bugs

- Move page cache out of the publicly served .bunext/public dir and hash cache keys
- Skip caching credentialed requests, non-2xx and Set-Cookie responses; cap entries
- Enforce API body size limit while reading; keep req body readable for handlers
- Hide error messages from clients in production
- Escape inline script JSON; strip cookies from HMR payloads
- Only trust X-Forwarded-Proto with trust_proxy config
- Fix console race in SSR, dotted page paths, middleware rewrites,
  excluded path status, encoded static file names, symlinked dirs
- Upgrade vulnerable deps, remove micromatch, pin bun versions, delete dead code

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-13 15:48:08 +01:00
co-authored by Claude Opus 5.5
parent 4238d9a4ea
commit 74103a19c9
37 changed files with 708 additions and 573 deletions
+16 -3
View File
@@ -9,6 +9,7 @@ import checkExcludedPatterns from "../../utils/check-excluded-patterns";
import { AppData } from "../../data/app-data";
import { log } from "../../utils/log";
import fullRebuild from "./full-rebuild";
import grabRouter from "../../utils/grab-router";
const HMR_RETRY_COOLDOWN_MS = 5000;
let lastHmrRetryTime = 0;
@@ -26,10 +27,13 @@ export default async function bunextRequestHandler({
let req = initial_req.clone();
try {
const url = new URL(req.url);
let url = new URL(req.url);
if (checkExcludedPatterns({ path: url.pathname })) {
return Response.json({ success: false, msg: `Invalid Path` });
return Response.json(
{ success: false, msg: `Invalid Path` },
{ status: 404 },
);
}
let response: Response | undefined = undefined;
@@ -47,6 +51,7 @@ export default async function bunextRequestHandler({
if (middleware_res instanceof Request) {
req = middleware_res;
url = new URL(req.url);
}
}
@@ -68,8 +73,16 @@ export default async function bunextRequestHandler({
response = await handleRoutes({ req });
} else if (url.pathname.startsWith("/public/")) {
response = await handlePublic({ req });
} else if (url.pathname.match(/\..*$/)) {
} else if (url.pathname.match(/\.[^/]+$/)) {
response = await handleFiles({ req });
// Paths like `/users/john.doe` look like files but can be pages.
if (
response.status == 404 &&
grabRouter()?.match(url.pathname)?.filePath
) {
response = await handleWebPages({ req });
}
} else {
response = await handleWebPages({ req });
}