Mar 8, 2026·6 min read·6 visits
CVE-2026-30861 is a critical RCE vulnerability in Tencent WeKnora caused by an incomplete command blacklist in the MCP `stdio` transport validation. Attackers bypass restrictions using the Node.js `-p` flag via `npx` to execute arbitrary system commands. The vendor patched this in version 0.2.10 by completely removing the `stdio` transport feature.
Tencent WeKnora versions 0.2.5 through 0.2.9 contain a critical vulnerability in the Model Context Protocol (MCP) configuration logic. The application implements an incomplete argument blacklist for the `stdio` transport type, allowing attackers to bypass validation using Node.js execution flags. Since WeKnora permits unrestricted user registration by default, remote attackers can register an account, configure a malicious MCP service, and achieve arbitrary code execution with the privileges of the application process.
Tencent WeKnora implements the Model Context Protocol (MCP) to facilitate interactions between large language models and local processes. The feature operates via the /api/v1/mcp-services endpoint, which accepts configuration payloads defining the local binary and arguments to execute. This transport mechanism, designated as stdio, relies on spawning child processes directly on the host operating system.
The application enforces access control on the MCP service creation endpoint, requiring a valid JSON Web Token (JWT). However, the default deployment configuration for WeKnora enables unrestricted user registration. Any remote attacker can interact with the registration endpoint to provision a local account and subsequently authenticate to the API. This default state converts an authenticated attack surface into an unauthenticated exposure vector.
Once authenticated, users can submit stdio configuration objects that the backend processes and executes. The vulnerability exists within the validation phase of these configuration objects. The system attempts to restrict execution to specific package runners, but the sanitization logic fails to account for language-specific execution flags. Attackers exploit this gap to escape the restricted execution context and run arbitrary system commands.
The underlying flaw is an incomplete list of disallowed elements (CWE-184) within the ValidateStdioArgs() function. The application attempts to secure the stdio transport by combining a base command whitelist with an argument blacklist. The whitelist correctly restricts the primary execution binary to npx (the Node.js package runner) and uvx (the Python uv package runner).
Following the whitelist check, the system processes the provided arguments against a regular expression blocklist named DangerousArgPatterns. This blocklist targets standard shell metacharacters such as semicolons, pipes, ampersands, and command substitution operators. It also identifies and rejects specific execution flags like -e and --eval to prevent direct script execution. The design assumes that restricting the primary binary and blocking shell chaining operators is sufficient to prevent arbitrary execution.
The implementation fails to account for the -p (or --print) flag in Node.js. When npx invokes node, the -p flag evaluates the subsequent string argument as JavaScript code and prints the result. Since the regex blocklist only looks for -e and --eval, the -p flag successfully passes validation. The evaluated JavaScript code executes within the Node.js context, providing access to powerful built-in modules such as child_process.
This validation bypass allows the attacker to inject a JavaScript payload that spawns a secondary shell, completely circumventing the initial restrictions placed on the npx binary.
The vulnerability history of this feature demonstrates the fundamental difficulty of implementing secure execution blacklists. In commit f7900a5e9a18c99d25cec9589ead9e4e59ce04bb, the developers introduced the ValidateStdioConfig mechanism. This initial patch attempted to secure the execution pipeline by explicitly allowing only uvx and npx, alongside the aforementioned regex blacklist. The code iterated through the arguments array, applying the regex, but omitted the p flag used for printing and evaluation.
The final remediation, implemented in commit 57d6fea8bc265ad28b385e0158957c870cff4b50, abandons the blacklist approach entirely in favor of attack surface reduction. The developers recognized that safely wrapping arbitrary CLI tools is practically impossible due to the diverse and evolving execution flags supported by underlying interpreters.
The patch modifies mcp_service.go by removing the ValidateStdioConfig function and updating the service creation handlers. The CreateMCPService and UpdateMCPService functions now explicitly reject any configuration specifying the stdio transport type.
// Patched logic in mcp_service.go
if req.TransportType == "stdio" {
return nil, errors.New("stdio transport type is disabled for security reasons")
}Additionally, the frontend component McpServiceDialog.vue was modified to remove the stdio configuration interface. This comprehensive removal ensures that the vulnerable code path can no longer be reached, providing a complete and robust fix.
Exploiting CVE-2026-30861 requires standard HTTP interaction with the WeKnora API. The attacker first provisions an account and extracts the required JWT from the authentication response. They then construct a malicious JSON payload directed at the /api/v1/mcp-services endpoint to define the execution parameters.
The core of the exploit payload relies on the stdio_config object. The command field is set to npx, bypassing the whitelist. The args array contains the specific execution sequence: node, -p, followed by the JavaScript execution string. A standard payload utilizes the require('child_process').execSync() method to execute system commands.
{
"name": "mcp-test-service",
"transport_type": "stdio",
"stdio_config": {
"command": "npx",
"args": [
"node",
"-p",
"require('child_process').execSync('id > /tmp/out')"
]
}
}Submitting this payload returns a unique service ID. The execution does not occur during creation. To trigger the payload, the attacker sends an empty POST request to the /api/v1/mcp-services/{id}/test endpoint. The backend processes the configuration, spawns the npx process with the provided arguments, and executes the JavaScript payload, resulting in system-level command execution.
The successful exploitation of CVE-2026-30861 grants the attacker arbitrary code execution privileges on the host system running the WeKnora application. The execution context is bound to the system user operating the WeKnora backend process. In typical containerized deployments, this often defaults to the root user, leading to total container compromise.
With system-level access, attackers can exfiltrate sensitive data stored within the WeKnora environment, including internal database credentials, API keys for external language models, and proprietary document corpuses used for semantic retrieval. The vulnerability provides a reliable initial access vector for lateral movement within the broader network infrastructure.
The Common Vulnerability Scoring System (CVSS v3.1) base score is 10.0. The severity reflects the low attack complexity, lack of necessary user interaction, and the default open registration policy that negates the theoretical authentication requirement. The exploit provides high impacts across confidentiality, integrity, and availability.
The primary remediation for CVE-2026-30861 is upgrading the Tencent WeKnora deployment to version 0.2.10 (or 2.0.10) or later. The patch completely removes the stdio transport type, eliminating the attack surface entirely. Administrators should review the release notes to understand the operational impact of losing the stdio functionality for MCP services.
Organizations unable to immediately apply the patch must implement strict mitigation controls. The most effective interim defense is restricting access to the /api/v1/mcp-services endpoint using a Web Application Firewall (WAF) or reverse proxy. The WAF should inspect incoming JSON payloads and drop any request where the transport_type key is set to stdio.
Furthermore, administrators should audit their WeKnora configuration to disable open user registration if it is not strictly required by the business use case. Post-incident response procedures should include reviewing application logs for POST requests to the MCP service creation endpoints and auditing the mcp_services database table for existing malicious configurations.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
WeKnora Tencent | 0.2.5 - 0.2.9 | 0.2.10 |
WeKnora Tencent | 2.0.5 - 2.0.9 | 2.0.10 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-78, CWE-184 |
| Attack Vector | Network |
| CVSS v3.1 Score | 10.0 |
| EPSS Score | 0.00209 |
| Impact | Remote Code Execution |
| Exploit Status | poc |
| CISA KEV | False |
Improper Neutralization of Special Elements used in an OS Command