mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 10:08:46 +02:00
Add security headers and proxy error handling to Hono server
Every response gets X-Frame-Options, X-Content-Type-Options, and Referrer-Policy (SEC-07/FE-08). Backend proxy failures now return a logged 502 instead of an opaque uncaught error (FE-23). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -324,6 +324,27 @@ class SuppressRenderToolTextMiddleware extends (Middleware as any) {
|
|||||||
|
|
||||||
const app = new Hono();
|
const app = new Hono();
|
||||||
|
|
||||||
|
// Security headers on every response. Responses returned by fetch() (the
|
||||||
|
// backend proxy) carry immutable headers, so rebuild the Response instead of
|
||||||
|
// mutating in place.
|
||||||
|
const SECURITY_HEADERS: Record<string, string> = {
|
||||||
|
"X-Frame-Options": "DENY",
|
||||||
|
"X-Content-Type-Options": "nosniff",
|
||||||
|
"Referrer-Policy": "strict-origin-when-cross-origin",
|
||||||
|
};
|
||||||
|
|
||||||
|
app.use("*", async (c, next) => {
|
||||||
|
await next();
|
||||||
|
const res = c.res;
|
||||||
|
const headers = new Headers(res.headers);
|
||||||
|
for (const [k, v] of Object.entries(SECURITY_HEADERS)) headers.set(k, v);
|
||||||
|
c.res = new Response(res.body, {
|
||||||
|
status: res.status,
|
||||||
|
statusText: res.statusText,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.all("/api/copilotkit/*", async (c) => {
|
app.all("/api/copilotkit/*", async (c) => {
|
||||||
const cookieHeader = c.req.header("cookie") ?? "";
|
const cookieHeader = c.req.header("cookie") ?? "";
|
||||||
const match = cookieHeader.match(/(?:^|;\s*)ws_token=([^;]+)/);
|
const match = cookieHeader.match(/(?:^|;\s*)ws_token=([^;]+)/);
|
||||||
@@ -398,7 +419,12 @@ const proxyToBackend = async (c: import("hono").Context) => {
|
|||||||
// @ts-expect-error undici requires duplex for streamed bodies
|
// @ts-expect-error undici requires duplex for streamed bodies
|
||||||
init.duplex = "half";
|
init.duplex = "half";
|
||||||
}
|
}
|
||||||
return fetch(target, init);
|
try {
|
||||||
|
return await fetch(target, init);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[proxy] ${method} ${url.pathname} → backend failed:`, err);
|
||||||
|
return c.json({ error: "Backend unavailable" }, 502);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
app.all("/api/v1/*", proxyToBackend);
|
app.all("/api/v1/*", proxyToBackend);
|
||||||
|
|||||||
Reference in New Issue
Block a user