Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
105 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard Summary PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication: It prints a deprecation warning, then launches the server with: Because config.auth is absent, createapp() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This is an incomplete hardening / sibling-callsite issue. The legacy feature handler in src/praisonai/praisonai/cli/features/recipe.py rejects the same non-localhost/no-auth combination, and current createauthmiddleware() now fails closed if API-key/JWT auth is selected without a secret. The installed Typer…
Recommended action: Upgrade to 4.6.59 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI ToolsMCPServer legacy SSE transport accepts attacker Host/Origin and exposes registered tools Summary praisonaiagents.mcp.ToolsMCPServer.runsse() builds a Starlette MCP HTTP+SSE server around mcp.server.sse.SseServerTransport. The server exposes /sse and /messages/, but it does not validate Origin, does not validate Host, and does not require any authentication. This is reachable through supported PraisonAI code paths that wrap configured MCP server tools and re-expose them over legacy SSE: - praisonai mcp run <name --transport sse - praisonai serve mcp --name <name --transport sse - direct use of ToolsMCPServer(...).runsse(...) or launchtoolsmcpserver(..., transport="sse") A malicious website can use DNS rebinding against a local or internal PraisonAI SSE MCP server and send requests with attacker-controlled Host and Origin headers. The local PoV binds only to 127.0.0.1, sends an attacker Host and Origin, lists the registered tool, and invokes it successfully. The same…
Recommended action: Upgrade to 4.6.59 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI Dynamic Context history and terminal tools read files outside configured storage via path traversal Summary PraisonAI's Dynamic Context module provides filesystem-backed history and terminal-log storage. The SDK reference describes the module as providing: - artifact storage for tool outputs, history, and terminal logs; - history persistence with search; and - terminal session logging. The module also exports agent-callable tool factories: - createhistorytools() returns historysearch, historytail, and historyget. - createterminaltools() returns terminaltail, terminalgrep, and terminalcommands. Those tools accept runid and agentid arguments from the tool caller. The underlying stores join those values into filesystem paths without rejecting absolute paths or .. traversal: Because runid can be an absolute path and agentid can contain traversal, a lower-trust prompt/user that can call these tools can read .jsonl and .log files outside the configured Dynamic Context base…
Recommended action: Upgrade to 4.6.59 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
DiscordApproval accepts unrelated channel messages as dangerous-tool approvals Summary praisonai.bots.DiscordApproval approves a pending dangerous tool call when it sees any later non-bot message in the configured Discord channel whose text is classified as approval, such as yes. The decision is not bound to: - a Discord reply to the approval message; - a Discord thread created for that request; - a Discord interaction/button callback for that request; - an explicit approver user allowlist; or - an approval nonce visible only to intended approvers. As a result, any user who can post in the configured approval channel can approve a pending high-risk tool call by sending yes after the approval message appears. The same local PoV also shows that the Slack and Telegram messaging approval backends have no explicit approver allowlist parameter, but the primary report-grade issue is the Discord backend's unthreaded channel cross-talk: the approving message does not need to be a reply or…
Recommended action: Upgrade to 4.6.59 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Bug Report: Arbitrary File Write in Python API Summary Hidden metadata in a webpage causes PraisonAI agents to write attacker-controlled content to arbitrary paths. writefile skips path validation when workspace=None (always None in production). Affected PraisonAI <= 4.6.37 (pip install praisonai) Root Cause code/tools/writefile.py:77-83 — path validation skipped when workspace=None. Attack Scenario 1. Attacker hosts a webpage containing hidden metadata: 2. Victim uses PraisonAI Python API to crawl and analyze that page (normal usage). 3. Agent sees outputfile: in context → autonomously calls writefile → writes to attacker-specified path. PoC Result All tool calls made by LLM autonomously. No code injection, no prompt injection instructions. Defense Status | Layer | Status | Reason | | ----------------- | ------------- | ---------------------------- | | Injection Defense | Not triggered | No injection patterns | | LLM Safety | Not triggered | Agent performing normal work | | Path…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The first-party PraisonAI A2A server example combines three behaviors into a remotely exploitable Critical chain: 1. The example exposes an A2A server without configuring authtoken. 2. The same example binds the server to 0.0.0.0. 3. The example registers a calculate(expression) tool implemented with Python eval(expression). An unauthenticated network client can send a JSON-RPC message/send request to /a2a. The A2A handler passes the attacker-controlled message to agent.chat(). With a real Gemini LLM (gemini/gemini-2.5-flash-lite), the model invoked the registered calculate tool, causing the example's eval() call to execute Python in the server process. The canary wrote a marker file from an unauthenticated /a2a request. This is not a claim that every A2A deployment is automatically RCE. The Critical chain is confirmed for the first-party A2A example, and for deployments that follow the same pattern: public unauthenticated A2A plus an unsafe tool such as this eval()-based…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for GHSA-9mqq-jqxf-grvw / CVE-2026-44336 is incomplete. The original advisory description named four vulnerable handlers in mcpserver/adapters/clitools.py: "registers four file-handling tools by default, praisonai.rules.create, praisonai.rules.show, praisonai.rules.delete, and praisonai.workflow.show. Each accepts a path or filename string from MCP tools/call arguments… with no containment check." Commit 68cc9427 ("fix(security): harden MCP rules path handling…") added a resolverulepath() helper and applied it to rules.create, rules.show, and rules.delete. workflow.show was left unchanged. Two adjacent handlers in the same file have the same pattern, workflow.validate and deploy.validate. Neither was mentioned in the original advisory. Both remain unchanged. The original advisory also identified the dispatcher (server.py:281-298) as a root cause. It accepts unvalidated kwargs from params["arguments"] with no enforcement against the tool's declared inputschema. That…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
executecode() in praisonaiagents/tools/pythontools.py (v1.6.37, subprocess sandbox mode) can be fully bypassed using print.self to retrieve the real Python builtins module, from which import can be extracted via vars() and runtime string construction. This achieves arbitrary OS command execution on the host, completely defeating the sandbox. This is a novel bypass that survives all patches for CVE-2026-39888 (frame traversal), CVE-2026-34938 (str subclass), and CVE-2026-40158 (type.getattribute trampoline). --- Severity CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — 9.9 Critical --- Root Cause Three independent gaps in the AST-based security validation: Gap 1: self missing from blockedattrs In CPython, all built-in functions (C-level functions) have a self attribute that returns the module they belong to. The built-in functions in safebuiltins (print, len, range, etc.) are the real CPython built-in functions, so print.self returns <module 'builtins' (built-in). The…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI's direct-prompt CLI automatically expands @url: mentions in raw prompt text before agent execution begins. If a prompt contains @url:<http-or-https-url, the CLI calls MentionsParser.process(...). The @url: handler then performs a direct urllib.request.urlopen() request to the attacker-controlled URL and returns the response body. That response body is prepended to the final model prompt context. There is no loopback/private-address restriction, no metadata-service restriction, and no approval gate before the fetch. As a result, attacker-influenced prompt text can cause the operator's machine to fetch localhost-only HTTP resources and inject the response into model context. Example: This causes PraisonAI to make an HTTP request to the local machine and prepend the fetched response body to the prompt that the model receives. This is a narrow local SSRF / local content disclosure issue in automatic prompt preprocessing. It is not a remote server takeover. Details The…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
CVE-2026-44338 (GHSA-6rmh-7xcm-cpxj) documents that PraisonAI ships a code-generator (praisonai.deploy.api.generateapiservercode) that emits a Flask API server with authentication disabled by default. Users who follow the documented quickstart (praisonai deploy --type api) get a server that: - binds to 0.0.0.0 per the recommended sample YAML - exposes /chat and /agents endpoints - runs praisonai.run() on user-supplied JSON input — LLM orchestration with the API key materials present in the process environment - does not require any authentication The PyPI wheel praisonai==4.6.33 (current @latest) still ships the generator with authenabled defaulting to False. The fix shape is opt-in via APIConfig(authenabled=True, authtoken=...). Details Anchor (file:line:symbol) - Vulnerable artifact: praisonai==4.6.33 on PyPI. - Defaults: praisonai/deploy/models.py:29 — authenabled: bool = Field(default=False, ...); praisonai/deploy/models.py:30 — authtoken: Optional[str] =…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI's call server exposes a network-facing agent control API without authentication when CALLSERVERTOKEN is not configured. The affected component is the praisonai.api.agentinvoke router as mounted by praisonai.api.call. The authentication helper verifytoken() fails open when CALLSERVERTOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALLSERVERTOKEN may unintentionally expose an unauthenticated remote agent control plane. Details The vulnerable behavior is caused by a fail-open authentication default. In praisonai/api/agentinvoke.py, CALLSERVERTOKEN is read from the environment: The…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI's spidertools URL validation can be bypassed using alternate loopback host encodings. The affected component is: The tool contains a URL validation function intended to block local or unsafe targets before fetching attacker-controlled URLs. However, the validation only blocks a small set of exact host strings such as localhost and 127.0.0.1. It does not normalize hostnames, resolve DNS, parse numeric IPv4 variants, or validate the final resolved IP address before making the request. As a result, URLs such as the following bypass the protection and still reach loopback services: After the weak validation passes, scrapepage() calls requests.Session.get() on the attacker-controlled URL. This allows an attacker who can influence URLs passed to scrapepage, crawl, or extracttext to induce SSRF requests against loopback-only services. This is a server-side request forgery protection bypass. Details The affected code is in: The vulnerable flow is: The validation appears to…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
<html<head</head<body<h2Arbitrary code execution via ungated <codespec.loader.execmodule</code in <codeagentsgenerator.py</code (v4.6.32 chokepoint refactor bypass)</h2 <h3Summary</h3 <pThe v4.6.32 chokepoint refactor (which patched CVE-2026-44334 / GHSA-xcmw-grxf-wjhj) added the <codePRAISONAIALLOWLOCALTOOLS</code env-var gate to the <codetooloverride.py</code sinks. However, <strongtwo additional <codespec.loader.execmodule</code call sites</strong in <codepraisonai/agentsgenerator.py</code were missed and remain completely unguarded on current <codemaster</code (v4.6.37). Both functions accept a <codemodulepath</code parameter sourced from YAML configuration and execute it without validation, signature checking, or the env-var gate.</p <h3Patch lineage</h3 CVE | GHSA | Fixed in | What was patched -- | -- | -- | -- CVE-2026-40156 | GHSA-2g3w-cpc4-chr4 | 4.5.128 | CWD tools.py auto-load in toolresolver.py CVE-2026-40287 | GHSA-g985-wjh9-qxxc | 4.5.139 | Env-var gate added to…
Recommended action: Upgrade to 4.6.40 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The safeextractall helper that all recipe pull, recipe publish, and recipe unpack flows route through validates each archive member's name for absolute paths, .. segments, and resolved-path escape — but does not validate member.linkname, does not reject symlink/hardlink members, and calls tar.extractall(destdir) without filter="data". A bundle that contains a symlink with a name inside destdir but a linkname pointing outside it, followed by a regular file whose path traverses through the just-created symlink, escapes destdir and lets the attacker write arbitrary content to an attacker-chosen location on the victim's filesystem. Affected paths Every code path that calls safeextractall is exposed: | Caller | File:line | |---|---| | praisonai recipe unpack | src/praisonai/praisonai/cli/features/recipe.py:1175 (introduced as the fix for GHSA-99g3-w8gr-x37c) | | LocalRegistry.unpack (recipe pull) | src/praisonai/praisonai/recipe/registry.py:413 | | Registry archive validation…
Recommended action: Upgrade to 4.6.37 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
praisonaiagents resolves unresolved tool names against module globals and main after it fails to match the declared tool list and the registry. With the default agent configuration, permallow is None, so undeclared non-dangerous tool names are not rejected by the permission gate. An attacker who can influence tool-call names can therefore invoke unintended application callables that were never declared as tools. Details The vulnerable resolution path is in toolexecution.py. After searching declared tools and the registry, execution falls back to globals() and then main: If a callable is found, it is executed directly: The permission gate does not enforce a declared-tool allowlist by default. In…
Recommended action: Upgrade to 4.6.37 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI's MCP (Model Context Protocol) server (praisonai mcp serve) registers four file-handling tools by default — praisonai.rules.create, praisonai.rules.show, praisonai.rules.delete, and praisonai.workflow.show. Each accepts a path or filename string from MCP tools/call arguments and joins it onto ~/.praison/rules/ (or, for workflow.show, accepts an absolute path) with no containment check. The JSON-RPC dispatcher passes params["arguments"] blind to each handler via kwargs without validating against the advertised input schema. By setting rulename="../../<some-path" an attacker walks out of the rules directory and writes any file the running user can write. Dropping a Python .pth file into the user site-packages directory escalates this primitive to arbitrary code execution in any subsequent Python process the user spawns — the next praisonai CLI invocation, an IDE script run, the user's python REPL, or any background Python service. The same primitive is reachable from:…
Recommended action: Upgrade to 4.6.34 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI exposes optional SQL/CQL-backed knowledge-store implementations that build table and index identifiers from unvalidated name and collection arguments. Applications that pass untrusted collection names into these backends can trigger SQL or CQL injection. Details This issue affects the public persistence layer exported by persistence/init.py, which exposes KnowledgeStore and createknowledgestore(). The factory wires the affected backends as supported knowledge-store providers in persistence/factory.py: - pgvector at persistence/factory.py - cassandra at persistence/factory.py - singlestorevector at persistence/factory.py The common root cause is that the KnowledgeStore interface accepts free-form collection names in createcollection(),…
Recommended action: Upgrade to 4.6.34 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI ships a legacy Flask API server with authentication disabled by default. When that server is used, any caller that can reach it can access /agents and trigger the configured agents.yaml workflow through /chat without providing a token. Details The vulnerable server is the shipped src/praisonai/apiserver.py entrypoint. - AUTHENABLED = False and AUTHTOKEN = None are hard-coded at src/praisonai/apiserver.py. - checkauth() returns True whenever authentication is disabled, so both protected routes fail open by design at src/praisonai/apiserver.py. - POST /chat only checks that the request JSON contains a message key and then runs PraisonAI(agentfile="agents.yaml").run() at…
Recommended action: Upgrade to 4.6.34 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
TL;DR CVE-2026-40287's fix gated tools.py auto-import behind PRAISONAIALLOWLOCALTOOLS=true in two files (toolresolver.py, api/call.py). A third import sink in praisonai/templates/tooloverride.py was missed and remains unguarded. It is reached by the recipe runner on every recipe execution and is remotely triggerable through POST /v1/recipes/run with a recipe value pointing at any local absolute path or any GitHub repo (because SecurityConfig.allowanygithub defaults to True). The attacker drops a tools.py next to TEMPLATE.yaml; the server execmodule()s it. No auth required by default, no environment opt-in required. Patch coverage gap CVE-2026-40287 was fixed in v4.5.139 by adding an env-var gate at: | File | Line | Gate | |---|---|---| | praisonai/toolresolver.py | 77 | if os.environ.get("PRAISONAIALLOWLOCALTOOLS", "").lower() != "true": | | praisonai/api/call.py | 80 | same | But the equivalent sinks in praisonai/templates/tooloverride.py were not patched: loadfromfile (line 84-94)…
Recommended action: Upgrade to 4.6.32 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for CVE-2026-40315 added input validation to SQLiteConversationStore only. Nine sibling backends — MySQL, PostgreSQL, async SQLite/MySQL/PostgreSQL, Turso, SingleStore, Supabase, SurrealDB — pass tableprefix straight into f-string SQL. Same root cause, same code pattern, same exploitation. 52 unvalidated injection points across the codebase. postgres.py additionally accepts an unvalidated schema parameter used directly in DDL. Severity High — CWE-89 (SQL Injection) CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N — 8.1 Exploitable in any deployment where tableprefix is derived from external input (multi-tenant setups, API-driven configuration, user-modifiable config files). Default config ("praison") is not affected. Details The CVE-2026-40315 fix added this guard to sqlite.py:52: The following backends perform the identical tableprefix → f-string SQL pattern without this guard: | Backend | File | Line | Injection points | | ---------------- |…
Recommended action: Upgrade to 4.5.149 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for PraisonAI's MCP command handling does not add a command allowlist or argument validation to parsemcpcommand(), allowing arbitrary executables like bash, python, or /bin/sh with inline code execution flags to pass through to subprocess execution. Affected Package - Ecosystem: PyPI - Package: MervinPraison/PraisonAI - Affected versions: < 47bff65413be - Patched versions: = 47bff65413be Details The vulnerability exists in src/praisonai/praisonai/cli/features/mcp.py in the MCPHandler.parsemcpcommand() method. This function parses MCP server command strings into executable commands, arguments, and environment variables. The pre-patch version performs no validation on the executable or arguments. The fix commit 47bff654 was intended to address command injection, but the patched parsemcpcommand() still lacks three critical controls: there is no ALLOWEDCOMMANDS allowlist of permitted executables (e.g., npx, uvx, node, python), there is no os.path.basename() validation to…
Recommended action: Upgrade to 4.5.149 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
praisonai browser start exposes the browser bridge on 0.0.0.0 by default, and its /ws endpoint accepts websocket clients that omit the Origin header entirely. An unauthenticated network client can connect as a fake controller, send startsession, cause the server to forward startautomation to another connected browser-extension websocket, and receive the resulting action/status stream back over that hijacked session. This allows unauthorized remote use of a connected browser automation session without any credentials. Details The issue is in the browser bridge trust model. The code assumes that websocket peers are trusted local components, but that assumption is not enforced. Relevant code paths: - Default network exposure: src/praisonai/praisonai/browser/server.py:38-44 and src/praisonai/praisonai/browser/cli.py:25-30 - Optional-only origin validation: src/praisonai/praisonai/browser/server.py:156-173 - Unauthenticated startsession routing:…
Recommended action: Upgrade to 4.5.139 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
praisonai workflow run <file.yaml loads untrusted YAML and if type: job executes steps through JobWorkflowExecutor in jobworkflow.py. This supports: - run: → shell command execution via subprocess.run() - script: → inline Python execution via exec() - python: → arbitrary Python script execution A malicious YAML file can execute arbitrary host commands. Affected Code - workflow.py → actionrun() - jobworkflow.py → execshell(), execinlinepython(), execpythonscript() PoC Create exploit.yaml: Run: Reproduction Steps 1. Save the YAML above as exploit.yaml. 2. Execute praisonai workflow run exploit.yaml. 3. Confirm pwned.txt appears in the working directory. Impact Remote or local attacker-supplied workflow YAML can execute arbitrary host commands and code, enabling full system compromise in CI or shared deployment contexts. Reporter: Lakshmikanthan K (letchupkt)
Recommended action: Upgrade to 4.5.139 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI automatically imports ./tools.py from the current working directory when launching certain components. This includes call.py, toolresolver.py, and CLI tool-loading paths. A malicious tools.py placed in the process working directory is executed immediately, allowing arbitrary Python code execution in the host environment. Affected Code - call.py → importtoolsfromfile() - toolresolver.py → loadlocaltools() - tools.py → local tool import flow - PoC Create tools.py in the directory where PraisonAI is launched: Run any PraisonAI component that loads local tools, for example: Reproduction Steps 1. Create a malicious tools.py in the current working directory. 2. Start PraisonAI or invoke a CLI command that loads local tools. 3. Verify that /tmp/pwned.txt or the malicious command output exists. Impact An attacker who can place or influence tools.py in the working directory can execute arbitrary code in the PraisonAI process, compromising the host and any connected data. Reporter:…
Recommended action: Upgrade to 4.5.139 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
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: This value is then used in queries such as: 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…
Recommended action: Upgrade to 4.5.133 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.