From dda4f4d4ed49f5a84776e6371526eadb76c1ea94 Mon Sep 17 00:00:00 2001 From: ajnart Date: Sat, 22 Aug 2026 12:57:48 +0200 Subject: [PATCH] fix(mcp): reject normalized base paths --- apps/nextjs/src/env.spec.ts | 2 ++ apps/nextjs/src/env.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/nextjs/src/env.spec.ts b/apps/nextjs/src/env.spec.ts index a84e46070..87a379afa 100644 --- a/apps/nextjs/src/env.spec.ts +++ b/apps/nextjs/src/env.spec.ts @@ -14,6 +14,8 @@ describe("BASE_URL", () => { "ftp://homarr.example.com", "https://user:password@homarr.example.com", "https://homarr.example.com/prefix", + "https://homarr.example.com/.", + "https://homarr.example.com/a/..", "https://homarr.example.com?preview=1", "https://homarr.example.com#preview", ])("rejects the non-origin URL %s", (value) => { diff --git a/apps/nextjs/src/env.ts b/apps/nextjs/src/env.ts index 4d97084ca..851fd219a 100644 --- a/apps/nextjs/src/env.ts +++ b/apps/nextjs/src/env.ts @@ -1,9 +1,11 @@ import { createBooleanSchema, createEnv } from "@homarr/core/infrastructure/env"; import { z } from "zod/v4"; +const httpOriginRegex = /^https?:\/\/[^/?#\\]+\/?$/i; + export const baseUrlSchema = z.url({ protocol: /^https?$/ }).refine((value) => { const url = new URL(value); - return !url.username && !url.password && url.pathname === "/" && !url.search && !url.hash; + return httpOriginRegex.test(value) && !url.username && !url.password; }, "BASE_URL must be an HTTP(S) origin without credentials, a path, query parameters, or a fragment"); export const env = createEnv({