Skip to content

Security Vulnerability: Command Injection in compile_mo tool of webasyst-mcp #1

Description

@cccccindy19

Summary

The MCP server webasyst-mcp is vulnerable to command injection due to unsafe use of execSync with user-controlled input in the compile_mo MCP tool.

Vulnerable Code

Details

Based on the reviewed code path, the issue involves app_id, locale, po, mo. The reviewed code path reaches a shell-string execution sink in a way that is inconsistent with the tool's documented scope.

The reviewed code does not use a stronger boundary such as argv-based process execution, a destination allowlist, parsed SQL enforcement, or another control that would make the execution step consistent with the tool's documented scope.

compile_mo

Confirmed user-controlled or user-selected values in the reviewed path: app_id, locale, po, mo.

Relevant code:

Tool handler and argument flow:

1300: // ========= Localization & release helpers =========
1301: async function generatePoTemplateTool({ app_id, locale = 'ru_RU' }) {
1302: 	const rootPath = await findWebasystRoot();
1303: 	const poDir = path.join(rootPath, 'wa-apps', app_id, 'locale', locale, 'LC_MESSAGES');
1304: 	await ensureDir(poDir);
1312: 
1313: async function compileMoTool({ app_id, locale = 'ru_RU' }) {
1314: 	const rootPath = await findWebasystRoot();
1315: 	const poPath = path.join(rootPath, 'wa-apps', app_id, 'locale', locale, 'LC_MESSAGES', `${app_id}.po`);
1316: 	const moPath = path.join(rootPath, 'wa-apps', app_id, 'locale', locale, 'LC_MESSAGES', `${app_id}.mo`);

Command / request / execution flow:

1304: 	await ensureDir(poDir);
1305: 	const poPath = path.join(poDir, `${app_id}.po`);
1306: 	if (!(await fileExists(poPath))) {
1307: 		const header = `msgid ""\nmsgstr ""\n"Project-Id-Version: ${app_id}\\n"\n"Content-Type: text/plain; charset=UTF-8\\n"\n"Language: ${locale}\\n"\n\n`;
1308: 		await fs.writeFile(poPath, header);
1309: 	}
1310: 	return { content: [{ type: 'text', text: `PO шаблон подготовлен: ${poPath}` }] };
1318: 	try {
1319: 		execSync(`msgfmt "${poPath}" -o "${moPath}"`);
1320: 		return { content: [{ type: 'text', text: `MO скомпилирован: ${moPath}` }] };
1321: 	} catch (e) {
1322: 		throw new Error('Не удалось выполнить msgfmt. Установите gettext.');

Impact

Inject additional shell syntax and execute unintended commands in the server environment.

Recommendation

  • Avoid passing user-controlled data through shell-string execution.
  • Use spawn, execFile, or equivalent argv-based execution APIs so arguments are not re-parsed by a shell.
  • Apply strict allowlists or structural validation to high-risk fields before they reach the sensitive sink.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions