GHSA-8w32-6mrw-q5wv: WeKnora Vulnerable to Remote Code Execution via SQL Injection Bypass in AI Database Query Tool
SummaryA critical Remote Code Execution (RCE) vulnerability exists in the application's database query functionality. The validation system fails to recursively inspect child nodes within PostgreSQL array expressions and row expressions, allowing attackers to bypass SQL injection protections. By smuggling dangerous PostgreSQL functions inside these expressions and chaining them with large object operations and library loading capabilities, an unauthenticated attacker can achieve arbitrary code execution on the database server with database user privileges.**Impact:** Complete system compromise with arbitrary code executionDetailsRoot Cause AnalysisThe application implements a 7-phase SQL validation framework in `internal/utils/inject.go` designed to prevent SQL injection attacks:| Phase | Validation Type | Status |
|-------|-----------------|--------|
| Phase 1 | Null byte and length checks | ✅ Working |
| Phase 2 | PostgreSQL AST parsing via `pg_query_go/v6` | ✅ Working |
| Phase 3 | Single statement enforcement | ✅ Working |
| Phase 4 | SELECT-only queries | ✅ Working |
| Phase 5 | Deep SELECT statement validation | ❌ **Incomplete** |
| Phase 6 | Table whitelist validation | ✅ Working |
| Phase 7 | Regex-based keyword detection | ✅ Working |Critical Vulnerability: Incomplete AST Node ValidationThe `validateNode()` function in Phase 5 fails to handle two critical PostgreSQL expression types: `ArrayExpr` (array expressions) and `RowExpr` (row expressions). This function recursively validates AST nodes to prevent dangerous operations, but lacks handlers for these node types.**Vulnerable Code Location:** `internal/utils/inject.go` - `validateNode()` function**Missing Handlers:**`node.GetArrayExpr()` - Not checked; child elements bypass validation`node.GetRowExpr()` - Not checked; child elements bypass validationAttack Vector: Smuggling Functions in Array ExpressionsBy placing dangerous PostgreSQL functions inside array expressions, attackers bypass all validation checks:**Why This Bypasses All Phases:****Phase 1:** No null bytes or length violation ✅**Phase 2:** Valid PostgreSQL syntax parses successfully ✅**Phase 3:** Single SELECT statement ✅**Phase 4:** Query is a SELECT statement ✅**Phase 5:** `validateNode()` reaches the `ArrayExpr` node but has no handler; skips validation of child nodes containing `pg_read_file()` ✅**Phase 6:** `knowledge_bases` is in the allowed table whitelist ✅**Phase 7:** Query does not contain blacklisted keywords (1=1, 0=0, and, or, etc.); regex check passes ✅PoCPrerequisitesAI agent configured with `database_query` toolAgent in "smart reasoning mode" with single tool iterationSystem prompt restricting tool usage to provided JSON only:Model: GLM from Z.AI (or equivalent with minimal safety restrictions)At least one knowledge base (can be empty)Step 1: Verify File Read CapabilitySend this prompt to the AI agent:**Expected Result:** The response contains the contents of `/etc/passwd` from the database server, proving arbitrary file read access.Example result:Step 2: Prepare Malicious PayloadCompile a minimal PostgreSQL shared library (`payload.so`):**Compile with size optimization:****Result:** `payload.so` (~5KB after optimization)Step 3: Create Malicious PostgreSQL ConfigurationCreate `/tmp/postgres.conf.new`:Encode as base64:Step 4: Upload PostgreSQL ConfigurationSend to AI agent (replace `BASE64_CONFIG` with output from Step 3):**Result:** Configuration file written to `/var/lib/postgresql/data/postgresql.conf`Step 5: Upload Payload Binary in ChunksEncode `payload.so` as base64 and split into chunks (each ~512 bytes when decoded):Send chunks via AI agent:**Result:** Binary payload uploaded in chunks to large object storageStep 6: Export Payload and Reload ConfigurationSend final steps to AI agent:Step 7: Trigger Code ExecutionUpon restart, PostgreSQL loads `payload.so` via `session_preload_libraries`, executing `_PG_init()` with database user privileges.**Verification:**PoC video:https://github.com/user-attachments/assets/d0253bd0-4099-4ef5-9824-3f88d0690da6Helper files used for reproducing:[helper.zip](https://github.com/user-attachments/files/24847390/helper.zip)ImpactAn unauthenticated attacker can achieve complete system compromise through Remote Code Execution (RCE) on the database server. By sending a specially crafted message to the AI agent, the attacker can:**Extract sensitive data** - Read entire database contents, system files, credentials, and API keys**Modify data** - Alter database records, inject backdoors, and manipulate audit logs**Disrupt service** - Delete tables, crash the database, or cause denial of service**Establish persistence** - Install permanent backdoors to maintain long-term access**Pivot laterally** - Use the compromised database to access other connected systems**CWE-89:** SQL Injection | **CWE-627:** Dynamic Variable Evaluation | **Type:** Remote Code ExecutionMitigationsFix AST node validation to recursively inspect array expressions and row expressions, ensuring all dangerous functions are caught regardless of nesting depthImplement a strict blocklist of dangerous PostgreSQL functions (pg_read_file, lo_from_bytea, lo_put, lo_export, pg_reload_conf, etc.)Restrict the application's database user to SELECT-only permissions with no execute rights on administrative functionsDisable dynamic library loading in PostgreSQL configuration by clearing dynamic_library_path and session_preload_libraries
CVSS v3.1: 10