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-30860
9.90.08%

CVE-2026-30860: Remote Code Execution via SQL Injection Bypass in Tencent WeKnora

Alon Barad
Alon Barad
Software Engineer

Mar 9, 2026·6 min read·6 visits

PoC Available

Executive Summary (TL;DR)

A logic flaw in WeKnora's SQL AST validation (<0.2.12) fails to parse Array/Row expressions. This enables attackers to bypass security filters, smuggle malicious PostgreSQL functions, and achieve RCE on the database server.

CVE-2026-30860 is a critical remote code execution vulnerability in Tencent WeKnora prior to version 0.2.12. The flaw exists in the AI-driven database query tool, where incomplete Abstract Syntax Tree (AST) validation allows attackers to bypass SQL injection protections. By encapsulating malicious PostgreSQL functions within unhandled Array or Row expressions, an attacker can achieve arbitrary file read, file write, and execute arbitrary code on the underlying database server.

Vulnerability Overview

Tencent WeKnora is an LLM-powered framework utilized for document understanding and retrieval. The application exposes an AI-driven database_query tool designed to allow agents to interact with underlying datasets. To secure this interface, WeKnora employs a multi-phase SQL validation framework intended to neutralize SQL injection attempts before they reach the database engine.

The core issue resides in the validation phase responsible for inspecting the PostgreSQL Abstract Syntax Tree (AST). The validator fails to recursively inspect specific container nodes, specifically ArrayExpr and RowExpr. This omission creates a significant blind spot in the input sanitization pipeline.

Attackers leverage this blind spot to smuggle restricted PostgreSQL administrative functions past the security filters. Because the validator ignores the contents of the array or row constructs, the embedded malicious functions are successfully passed to the database. Execution of these functions grants the attacker arbitrary file read/write capabilities, which can be escalated to full remote code execution on the host operating system.

Technical Root Cause Analysis

The vulnerability originates in internal/utils/inject.go within the validateNode function. This function implements a 7-phase validation framework using the pg_query_go library to parse incoming SQL statements into an AST. The application relies on traversing this AST to identify and block forbidden SQL constructs or function calls.

Prior to version 0.2.12, the AST traversal logic operated on a fail-open model for unrecognized node types. The function contained explicit handlers for standard nodes such as FuncCall, ColumnRef, and TypeCast. If a node type matched one of these explicitly defined handlers, the validator recursively inspected its children. However, if the node type was not recognized, the function simply returned nil (success), halting recursion for that branch of the tree.

The validateNode function lacked handlers for ArrayExpr and RowExpr nodes, which are generated when parsing PostgreSQL ARRAY[...] and ROW(...) constructs. When the parser encountered these nodes, it ceased further inspection of their contents. This allowed any function call or subquery nested within an array or row declaration to completely bypass Phase 5 (Deep SELECT validation) and Phase 7 (Regex keyword detection).

Code Analysis and Patch Review

The vulnerable implementation of validateNode demonstrates the failure to enforce a deny-by-default boundary. The function iterated through known node types but permitted the AST traversal to exit cleanly when encountering unhandled structures.

// Vulnerable Implementation: internal/utils/inject.go
func (v *sqlValidator) validateNode(node *pg_query.Node, result *SQLValidationResult) error {
    if node == nil { return nil }
 
    // Existing handlers descend into children
    if fc := node.GetFuncCall(); fc != nil { /* ... */ }
    if cr := node.GetColumnRef(); cr != nil { /* ... */ }
    if tc := node.GetTypeCast(); tc != nil { /* ... */ }
 
    // Missing handlers for ArrayExpr and RowExpr.
    // Function returns nil, silently ignoring child nodes.
    return nil 
}

The primary fix, introduced in commit 01d1aeab0ee989a18b6eec2c9a7353f7fb2c852c, replaces the fail-open logic with comprehensive, explicit handling of all possible AST nodes. The patch adds specific handlers for AArrayExpr, RowExpr, XmlExpr, and JsonExpr to ensure recursion continues down every branch of the AST. Furthermore, the patch enforces a strict blacklist against dangerous PostgreSQL function prefixes (pg_, lo_, dblink_, file_, copy_).

A subsequent hardening patch (commit 90ebd492ce151e24f468cb89f18ffc0aa75884c6) introduced table whitelisting. This restricts the target tables to knowledge_bases, knowledges, and chunks. This defense-in-depth measure limits the attack surface even if future AST parsing discrepancies are discovered, as attackers can no longer query arbitrary internal catalog tables.

Exploitation Methodology

Exploitation requires chaining the AST parser bypass with PostgreSQL administrative functions to escalate from SQL injection to arbitrary system command execution. The initial phase typically involves verifying the bypass by extracting sensitive system files using pg_read_file encapsulated in an array.

-- Phase 1: File exfiltration bypass
SELECT name, ARRAY[pg_read_file('/etc/passwd')] FROM knowledge_bases LIMIT 1

To achieve remote code execution, the attacker leverages the PostgreSQL Large Object (LO) facility. The attacker uses lo_from_bytea and lo_put to write the hexadecimal representation of a compiled, malicious shared object (.so) file into the database. The attacker then uses lo_export wrapped in an ARRAY[...] construct to write this payload to the filesystem, typically in /tmp/payload.so.

-- Phase 2: Arbitrary File Write via Large Objects
SELECT name, ARRAY[(lo_export(1712594153, '/tmp/payload.so')::text), 'safe'] FROM knowledge_bases LIMIT 1

The final step involves altering the database configuration to load the malicious shared object. The attacker overwrites postgresql.conf via lo_export to modify dynamic_library_path and session_preload_libraries. Execution is triggered by invoking pg_reload_conf() through the same array bypass technique. Upon reloading, the PostgreSQL daemon executes the code contained within the _PG_init() function of the malicious library.

Impact Assessment

The successful exploitation of CVE-2026-30860 results in a complete compromise of the database system. The attacker gains the ability to execute arbitrary commands on the host operating system with the privileges of the PostgreSQL service account (commonly postgres).

The CVSS v3.1 vector evaluates to CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H, yielding a base score of 9.9. The requirement for a low-privileged role (PR:L) indicates that the attacker must have network access and potentially basic application access to interact with the database_query tool, though some configurations expose this tool to unauthenticated users via the agent interface.

Beyond immediate host takeover, the access allows attackers to exfiltrate the entirety of the database, including proprietary knowledge bases, user credentials, and chat histories. The OS-level access facilitates lateral movement across the internal network and permits the establishment of persistent backdoors directly within the database engine or host operating system.

Remediation and Mitigation

The primary remediation for CVE-2026-30860 is to upgrade the Tencent WeKnora application to version 0.2.12 or later. This release contains the finalized AST validation logic that properly handles all required node types and implements strict whitelisting for both tables and functions.

As a defense-in-depth measure, administrators must enforce the principle of least privilege on the PostgreSQL user account utilized by WeKnora. The application database user must be restricted exclusively to SELECT, INSERT, UPDATE, and DELETE operations on required application tables. The account must possess zero execute privileges for administrative functions, specifically pg_read_file, pg_write_file, and the entire lo_* large object function suite.

If immediate patching is not technically feasible, administrators should disable the database_query tool within the WeKnora configuration. Organizations should deploy network monitoring and Web Application Firewall (WAF) rules to detect and block SQL queries containing unexpected ARRAY[...] or ROW(...) constructs paired with file system or large object function names.

Official Patches

TencentOfficial GitHub Security Advisory

Fix Analysis (2)

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.08%
Top 100% most exploited

Affected Systems

Tencent WeKnora (< 0.2.12)PostgreSQL instances connected to vulnerable WeKnora deployments

Affected Versions Detail

Product
Affected Versions
Fixed Version
WeKnora
Tencent
< 0.2.120.2.12
AttributeDetail
CWE IDCWE-89, CWE-627
Attack VectorNetwork
CVSS v3.19.9 (Critical)
EPSS Score0.00077
ImpactArbitrary Code Execution
Exploit StatusProof of Concept Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1105Ingress Tool Transfer
Command and Control
T1059Command and Scripting Interpreter
Execution
CWE-89
SQL Injection

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

References & Sources

  • [1]GitHub Advisory: GHSA-8w32-6mrw-q5wv
  • [2]Tencent/WeKnora Repository
  • [3]NVD Entry for CVE-2026-30860

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.