diff --git a/middleware.ts b/middleware.ts index 6f1bba2e..3ea8cb5e 100644 --- a/middleware.ts +++ b/middleware.ts @@ -19,25 +19,31 @@ export default function middleware(request: NextRequest) { headerObj[key] = value; }); - // Defensive URL correction - // If the URL contains 0.0.0.0 (internal IP), we rebuild it using the Host header + // Defensive URL correction for internal container leakage (0.0.0.0, klz-app, localhost) + // This prevents hydration mismatches and host poisoning in generated links/metadata. + const urlObj = new URL(url); + const internalHosts = ['0.0.0.0', 'klz-app', 'localhost', '127.0.0.1']; + let effectiveRequest = request; - if (url.includes('0.0.0.0')) { + if (internalHosts.includes(urlObj.hostname)) { const proto = headers.get('x-forwarded-proto') || 'https'; - const host = headers.get('x-forwarded-host') || headers.get('host') || 'testing.klz-cables.com'; - const newUrl = new URL(url); - newUrl.protocol = proto; - // Split host to remove port if present - const [hostname] = host.split(':'); - newUrl.hostname = hostname; - newUrl.port = ''; // Explicitly clear the port to avoid leaking :3000 - effectiveRequest = new NextRequest(newUrl, { + // Prioritize x-forwarded-host (passed by Traefik) over the local Host header + const hostHeader = + headers.get('x-forwarded-host') || headers.get('host') || 'testing.klz-cables.com'; + const [publicHostname] = hostHeader.split(':'); + + urlObj.protocol = proto; + urlObj.hostname = publicHostname; + urlObj.port = ''; // Explicitly clear internal port (3000) + + effectiveRequest = new NextRequest(urlObj, { headers: request.headers, method: request.method, body: request.body, }); + console.log( - `Replaced 0.0.0.0 URL with: ${newUrl.toString()} | Original Host: ${headers.get('host')} | Forwarded Host: ${headers.get('x-forwarded-host')}`, + `🛡️ Middleware: Fixed internal URL leak: ${url} -> ${urlObj.toString()} | Proto: ${proto} | Host: ${hostHeader}`, ); } diff --git a/varnish/default.vcl b/varnish/default.vcl index 1b4eb445..70bd3492 100644 --- a/varnish/default.vcl +++ b/varnish/default.vcl @@ -3,7 +3,7 @@ vcl 4.1; import std; probe default_probe { - .url = "/en"; + .url = "/health"; .timeout = 2s; .interval = 5s; .window = 5;