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; }