From 46e82aa529359019221dcae923e4427fe034a8bb Mon Sep 17 00:00:00 2001 From: Alec McLeod Date: Mon, 8 Jun 2026 14:12:30 -0300 Subject: [PATCH] Fix $-pattern corruption of user_config values in replaceVariables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String.prototype.replace treats $ sequences ($&, $$, $`, $', $n) in the replacement string as special patterns, so any user_config value containing a $ — e.g. a password with $& in it — was silently corrupted before being injected into mcp_config. The server then received wrong credentials. Pass a replacement function so the value is inserted verbatim. Adds a regression test covering $&, $$ and $n in a substituted value. --- src/shared/config.ts | 6 +++++- test/config.test.ts | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/shared/config.ts b/src/shared/config.ts index 7073f58..7a38134 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -34,7 +34,11 @@ export function replaceVariables( { key, replacement }, ); } else { - result = result.replace(pattern, replacement); + // Use a replacement function so that `$` sequences in the value + // (e.g. `$&`, `$$`, `$1`) are inserted literally rather than being + // interpreted as String.prototype.replace special patterns. This + // matters for secrets such as passwords that may contain `$`. + result = result.replace(pattern, () => replacement); } } } diff --git a/test/config.test.ts b/test/config.test.ts index 7e29f69..e2fa3c6 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -29,6 +29,15 @@ describe("replaceVariables", () => { consoleWarnSpy.mockRestore(); }); + it("should insert values containing $ patterns literally", () => { + // `$&`, `$$`, `$1` etc. are special in String.prototype.replace's + // replacement string — secrets containing them must be inserted verbatim. + const result = replaceVariables("${user_config.password}", { + "user_config.password": "pa$&ss$$wo$1rd", + }); + expect(result).toBe("pa$&ss$$wo$1rd"); + }); + it("should replace variables in objects", () => { const result = replaceVariables( { message: "Hello ${name}!" },