From 50846c000d89c716e2920cf51450767156549254 Mon Sep 17 00:00:00 2001 From: tahodev Date: Sat, 26 Sep 2026 03:21:19 +0900 Subject: [PATCH] fix(server): tolerate malformed percent-encoding in MongoDB URI database extractDatabaseFromMongoUri ran decodeURIComponent on the URI path without guarding against URIError. URL parsing does not validate percent-encoding, so a connection string whose database path contains a literal "%" or truncated escape (for example db%zz) crashed the relay with an uncaught URIError before any validation could run. Treat an undecodable path like an unparseable URI and return null, which matches the existing URL.canParse guard just above. Adds a regression test that fails with URIError: URI malformed before the fix. --- .../server/src/services/mongodb/relay.test.ts | 15 +++++++++++++++ packages/server/src/services/mongodb/relay.ts | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/server/src/services/mongodb/relay.test.ts b/packages/server/src/services/mongodb/relay.test.ts index cc932406..4baf3ac4 100644 --- a/packages/server/src/services/mongodb/relay.test.ts +++ b/packages/server/src/services/mongodb/relay.test.ts @@ -49,4 +49,19 @@ describe("mongodb relay", () => { ])("rejects %s", async (_label, invoke, message) => { await expect(invoke()).rejects.toThrow(message); }); + + it("treats a connection string with malformed percent-encoding as having no URI database", async () => { + await expect( + listMongoCollections({ + credentials: { + connectionString: "mongodb://user:pass@localhost:27017/db%zz", + database: "admin", + type: "mongodb" as const, + }, + request: { database: "other" }, + }) + ).rejects.toThrow( + 'Database "other" is not allowed by this data source configuration' + ); + }); }); diff --git a/packages/server/src/services/mongodb/relay.ts b/packages/server/src/services/mongodb/relay.ts index 73cc5d7a..611a2a8c 100644 --- a/packages/server/src/services/mongodb/relay.ts +++ b/packages/server/src/services/mongodb/relay.ts @@ -187,7 +187,16 @@ function extractDatabaseFromMongoUri(connectionString: string): string | null { } const url = new URL(normalizedConnectionString); const pathname = url.pathname ? url.pathname.replace(/^\//, "") : ""; - const decoded = decodeURIComponent(pathname).trim(); + // Comment: URL parsing does not validate percent-encoding, so a connection + // string whose database path contains malformed escapes (for example a + // literal "%") must be treated like an unparseable URI instead of crashing + // with an uncaught URIError. + let decoded: string; + try { + decoded = decodeURIComponent(pathname).trim(); + } catch { + return null; + } if (decoded.length === 0) { return null; }