replaceVariables interpolates the variable key into a RegExp unescaped (over-match + crash/ReDoS)

Open Beginner friendly
#262 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript
Domain
tooling

Research direction

Start in src/shared/config.ts at replaceVariables and inspect how the key is used to build the RegExp. Reproduce the over-match and invalid-key crash described in the issue, then verify that metacharacters in keys are treated literally without changing replacement values.

Written by the indexing model from the issue text.

Description

Summary

In replaceVariables (src/shared/config.ts), the variable key is interpolated raw into a RegExp source string, so regex metacharacters in the key are not treated literally. This causes (a) over-matching — the . in keys like user_config.cs_password matches any character — and (b) a hard crash / ReDoS if a manifest's user_config key contains a metacharacter (the schema allows arbitrary string keys).

This is distinct from #258 (which is about $ in the replacement value); this is about the key in the pattern.

Mechanism

src/shared/config.ts:27:

const pattern = new RegExp(`\\$\\{${key}\\}`, "g");

key is user_config.<name> (plus built-ins). The . is an unescaped metacharacter.

Reproduction (executed)
  • Over-match: variables = { "user_config.cs_password": "SECRET_PW" }, template "${user_config_cs_password}" (underscore where the dot is) → "SECRET_PW". Expected: unchanged.
  • Crash: a user_config key named [ yields new RegExp("\\$\\{user_config.[\\}","g")SyntaxError: Invalid regular expression: Unterminated character class, thrown from the string branch that runs for every string in the config, so getMcpConfigForManifest throws for an otherwise valid manifest. A key like (a+)+ is a ReDoS vector.
Suggested fix

Escape the key before building the regex:

const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = new RegExp(`\\$\\{${escaped}\\}`, "g");

(The replacement-function fix for #258 handles $ in the value; this handles metacharacters in the key.)

Environment: current main (70fe3b3).

Dominant language
TypeScript
Stars
2.1k
Forks
210
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from modelcontextprotocol/mcpb

All issues in modelcontextprotocol/mcpb

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.