[ ⌘K ]
← BACK TO SEARCH

Movin-T/mcp_basic_typescript

critical

ModelContextProtocol Server and Client project using the Typescript SDK

This MCP server provides a test interface for managing user data, including reading all users or a specific user's profile from a local JSON file, cre...

purpose: This MCP server provides a test interface for manathreat: local only
TypeScript0May 20, 2026May 20, 2026GITHUB
5/20/2026
high1 finding
src/server.ts
126    const res = await server.server.request(
127      {
128        method: 'sampling/createMessage',
129        params: {
130          messages: [
131            {
132              role: 'user',
133              content: {
134                type: 'text',
135                text: 'Generate fake user data. The user should have a realistic name, email, address, and phone number. Return this data as a JSON object with no other text or formatter so it can be used with JSON.parse.',
136              },
137            },
138          ],
139          maxTokens: 1024,
140        },
141      },
142      CreateMessageResultSchema
143    );
src/server.ts:126

// Local-only MCP, requires compromised LLM or prompt injection from another tool to exploit.

The create-random-user tool sends a fixed prompt to the LLM via sampling/createMessage. If an attacker can control the LLM's behavior (e.g., through a compromised model or prompt injection in another tool), the LLM could return malicious JSON that, when parsed and passed to createUser, could lead to arbitrary data being written to the users.json file. Additionally, the prompt itself is hardcoded and does not sanitize any user input, but the vulnerability is that the LLM output is trusted and directly used.

ImpactAn attacker who can influence the LLM's output (e.g., via prompt injection in another tool or compromised model) could inject arbitrary user data into the database, potentially overwriting or corrupting existing data. Since the tool is local-only, exploitation requires a compromised LLM or prompt injection from another tool.

FixValidate the LLM output against a strict schema before using it. Ensure that the generated JSON contains only expected fields (name, email, address, phone) and that values are sanitized. Consider using a whitelist of allowed characters or types.

medium1 finding
src/server.ts
85server.tool(
86  'create-user',
87  'Create a new user in the database',
88  {
89    name: z.string(),
90    email: z.string().email(),
91    address: z.string(),
92    phone: z.string(),
93  },
94  ...
95  async (params) => {
96    try {
97      const id = await createUser(params);
98      return {
99        content: [{ type: 'text', text: `User ${id} created successfully` }],
100      };
101    } catch {
102      return {
103        content: [{ type: 'text', text: 'Failed to save user' }],
104      };
105    }
106  }
107);
src/server.ts:85

// Local-only MCP, exploitation requires attacker to send crafted prompts to the tool.

The create-user tool accepts name, address, and phone as plain strings with no length or content restrictions. While email is validated with z.string().email(), the other fields are not sanitized. This could allow injection of special characters or excessively long strings that might cause issues when written to the JSON file or when read by other tools.

ImpactAn attacker could provide malicious input (e.g., very long strings, special characters) that could corrupt the JSON file or cause parsing errors in other tools that read the file. However, since the data is only stored in a local JSON file and not executed, the impact is limited to data corruption or denial of service.

FixAdd length limits and sanitization for name, address, and phone fields. Use zod schemas with .max() and .regex() to restrict input to safe characters.

medium1 finding
src/server.ts
172server.prompt(
173  'generate-fake-user',
174  'Generate a fake user based on a given name',
175  {
176    name: z.string(),
177  },
178  ({ name }) => {
179    return {
180      messages: [
181        {
182          role: 'user',
183          content: {
184            type: 'text',
185            text: `Generate a fake user with the name ${name}. The user should have a realisting email, address, and phone number.`,
186          },
187        },
188      ],
189    };
190  }
191);
src/server.ts:172

// Local-only MCP, requires compromised LLM to exploit

The generate-fake-user prompt directly interpolates user input (the name parameter) into the LLM prompt without sanitization. An attacker could inject additional instructions into the prompt, potentially causing the LLM to generate malicious or unintended output.

ImpactA compromised LLM or an attacker controlling the prompt input could manipulate the LLM to generate arbitrary content, which could be used for social engineering or to produce harmful responses. However, since this is a prompt that returns messages to the client, the impact is limited to the LLM output.

FixSanitize or escape user input before interpolating into the prompt. Consider using a template that does not allow arbitrary injection, or validate the input to ensure it only contains expected characters.

medium1 finding
src/server.ts
126const res = await server.server.request(
127      {
128        method: 'sampling/createMessage',
129        params: {
130          messages: [
131            {
132              role: 'user',
133              content: {
134                type: 'text',
135                text: 'Generate fake user data. The user should have a realistic name, email, address, and phone number. Return this data as a JSON object with no other text or formatter so it can be used with JSON.parse.',
136              },
137            },
138          ],
139          maxTokens: 1024,
140        },
141      },
142      CreateMessageResultSchema
143    );
src/server.ts:126

// Local-only MCP, requires compromised LLM to exploit

The create-random-user tool uses LLM sampling to generate fake user data. The prompt is hardcoded and does not incorporate any user input, so direct prompt injection is not possible. However, the tool relies on the LLM to produce valid JSON, and a compromised LLM could return malicious data that is then parsed and written to the users.json file. This is a prompt injection surface because the LLM output is trusted without validation.

ImpactA compromised LLM could inject arbitrary fields or values into the user object, potentially leading to data corruption or injection of malicious content into the JSON file. However, the impact is limited because the data is only written to a local JSON file and not executed.

FixValidate the structure and types of the parsed JSON before writing to the database. Use a schema validation library like Zod to ensure only expected fields are present and of the correct type.

low1 finding
src/server.ts
115server.tool(
116  'create-random-user',
117  'Create a random user with fake data',
118  {
119    title: 'Create Random User',
120    readOnlyHint: false,
121    destructiveHint: false,
122    idempotentHint: false,
123    openWorldHint: true,
124  },
125  async () => {
126    const res = await server.server.request(
127      {
128        method: 'sampling/createMessage',
129        params: {
130          messages: [
131            {
132              role: 'user',
133              content: {
134                type: 'text',
135                text: 'Generate fake user data...',
136              },
137            },
138          ],
139          maxTokens: 1024,
140        },
141      },
142      CreateMessageResultSchema
143    );
144    ...
145  }
146);
src/server.ts:115

// Local-only MCP, low impact as it only affects user experience.

The create-random-user tool uses the sampling/createMessage MCP method to generate fake user data. This method may require user consent or approval depending on the client implementation, but the tool does not explicitly request or handle user confirmation. The tool is marked with openWorldHint: true, but the sampling request could be unexpected to the user.

ImpactA user might not expect that invoking create-random-user will trigger an LLM sampling request, which could consume tokens or produce unexpected output. However, this is a minor usability issue rather than a security vulnerability.

FixConsider adding a confirmation step or documenting that the tool uses LLM sampling. Alternatively, generate fake data locally instead of relying on LLM.

filesystem.writeenv.exposure
75
LLM-based
low findings+5
high findings+25
medium findings+45
scoringcompleted