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
50 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
SpiderTools redirect-target SSRF protection bypass Summary SpiderTools.scrapepage() validates the initial URL and rejects direct loopback, private, link-local, metadata, and internal hostnames. It then calls requests.Session.get() without disabling automatic redirects or validating redirect Location targets. Requests follows redirects by default for GET requests. A safe-looking public URL can therefore pass validateurl(), redirect to a blocked target such as 127.0.0.1 or 169.254.169.254, and have the redirected response body parsed and returned by scrapepage(). The same sink is used by extractlinks(), crawl(), and extracttext() through their calls to scrapepage(). Affected component Tested affected: - v3.9.24 / d08d98ca - v3.9.26 / 62472a23 - v4.6.56 / d3c4a2af - v4.6.57 / e90d92231853161ad931f3498da57651a9f8b528 - current main 2f9677abb2ea68eab864ee8b6a828fd0141612e1 No patched version is known at report time. Root cause Current main validates only the caller-supplied URL: The fetch…
Recommended action: Upgrade to 1.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 1.6.59 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The SSE (Server-Sent Events) server in src/praisonai-agents/praisonaiagents/server/server.py exposes a /publish endpoint that broadcasts arbitrary messages to all connected clients without any authentication. The ServerConfig dataclass (line 24) defines an authtoken field, but this token is never validated in the /publish or /events request handlers. Any attacker with access to the SSE server port can inject arbitrary events into the SSE stream visible to all connected clients, or use /info to leak server configuration including connected client count. Details Vulnerable code (lines 164–180): The authtoken field in ServerConfig (line 31): This authtoken is never referenced in any request handler. The /publish endpoint processes any POST request regardless of authentication headers. The /info endpoint (line 182) also has no auth and returns server configuration including self.config.todict(). Routes registration (lines 190–194): No authentication middleware or token validation…
Recommended action: Upgrade to 1.6.59 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 1.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 1.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 1.6.40 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 1.6.37 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The URL checking logic in PraisonAI has a logical flaw that could be bypassed by attackers, leading to SSRF attacks. Details The current PraisonAI project uses validateurl to validate the input URL. The main logic is to perform security checks on the host portion of the URL extracted by urlparse to prevent SSRF attacks. <img width="1290" height="1145" alt="QQ20260424-151256-24-1" src="https://github.com/user-attachments/assets/d5f16b74-5ad2-444f-8600-b05f78a4b769" / However, there are indeed differences in parsing between urlparse and the library that actually sends the request. Currently, almost all application scenarios in this project involve first using validateurl for URL validation, and then using getsession().get to send the request. <img width="1143" height="740" alt="QQ20260424-151437-24-2" src="https://github.com/user-attachments/assets/b1bf6ec2-d32a-4dac-b814-da819e8d3c83" / In reality, its underlying mechanism is requests.get. <img width="1042" height="576"…
Recommended action: Upgrade to 1.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 1.6.8 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 1.5.140 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 1.5.140 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 1.5.140 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The approval system in PraisonAI Agents caches tool approval decisions by tool name only, not by invocation arguments. Once a user approves executecommand for any command (e.g., ls -la), all subsequent executecommand calls in that execution context bypass the approval prompt entirely. Combined with os.environ.copy() passing all process environment variables to subprocesses, this allows an LLM agent (potentially via prompt injection) to silently exfiltrate API keys and credentials without further user consent. Details The requireapproval decorator in src/praisonai-agents/praisonaiagents/approval/init.py:176-178 checks approval status by tool name only: The markapproved function in registry.py:144-147 stores only the tool name string: The approval context is never cleared during agent execution — clearapproved() exists (registry.py:152) but is never called in the agent's tool execution path (agent/toolexecution.py). Meanwhile, the ConsoleBackend UI at backends.py:95-96 misleads…
Recommended action: Upgrade to 4.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
| Field | Value | |---|---| | Severity | High | | Type | SSRF -- unvalidated URL in webcrawl httpx fallback allows internal network access | | Affected | src/praisonai-agents/praisonaiagents/tools/webcrawltools.py:133-180 | Summary webcrawl's httpx fallback path passes user-supplied URLs directly to httpx.AsyncClient.get() with followredirects=True and no host validation. An LLM agent tricked into crawling an internal URL can reach cloud metadata endpoints (169.254.169.254), internal services, and localhost. The response content is returned to the agent and may appear in output visible to the attacker. This fallback is the default crawl path on a fresh PraisonAI installation (no Tavily key, no Crawl4AI installed). Details The vulnerable code is in tools/webcrawltools.py:148-155: No scheme restriction, no hostname resolution, no private/link-local IP check. followredirects=True also means an attacker can use an open redirect on a public URL to bounce the request into internal…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The AGUI endpoint (POST /agui) has no authentication and hardcodes Access-Control-Allow-Origin: on all responses. Combined with Starlette/FastAPI's Content-Type-agnostic JSON parsing, any website a victim visits can silently trigger arbitrary agent execution against a locally-running AGUI server and read the full response, including tool execution results and potentially sensitive data from the victim's environment. Details The vulnerability is a combination of three issues in src/praisonai-agents/praisonaiagents/ui/agui/agui.py: 1. No authentication (line 124-125): The endpoint accepts any request. RunAgentInput (defined in types.py:159-165) has no auth token, API key, or session validation field. No middleware or dependencies are attached to the router (line 111). 2. Hardcoded wildcard CORS (line 131-141): The Access-Control-Allow-Origin: header is hardcoded in the library code. Library consumers cannot override this without patching the source. 3. CORS preflight bypass via…
Recommended action: Upgrade to 4.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The listfiles() tool in FileTools validates the directory parameter against workspace boundaries via validatepath(), but passes the pattern parameter directly to Path.glob() without any validation. Since Python's Path.glob() supports .. path segments, an attacker can use relative path traversal in the glob pattern to enumerate arbitrary files outside the workspace, obtaining file metadata (existence, name, size, timestamps) for any path on the filesystem. Details The validatepath() method at filetools.py:25 correctly prevents path traversal by checking for .. segments and verifying the resolved path falls within the current workspace. All file operations (readfile, writefile, copyfile, etc.) route through this validation. However, listfiles() at filetools.py:114 only validates the directory parameter (line 127), while the pattern parameter is passed directly to Path.glob() on line 130: Python's Path.glob() resolves .. segments in patterns (tested on Python 3.10–3.13),…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The executecommand function in shelltools.py calls os.path.expandvars() on every command argument at line 64, manually re-implementing shell-level environment variable expansion despite using shell=False (line 88) for security. This allows exfiltration of secrets stored in environment variables (database credentials, API keys, cloud access keys). The approval system displays the unexpanded $VAR references to human reviewers, creating a deceptive approval where the displayed command differs from what actually executes. Details The vulnerable code is in src/praisonai-agents/praisonaiagents/tools/shelltools.py: The security problem is a disconnect between the approval display and actual execution: 1. The LLM generates a tool call: executecommand(command="cat $DATABASEURL") 2. checktoolapprovalsync in toolexecution.py:558 passes {"command": "cat $DATABASEURL"} to the approval backend 3. ConsoleBackend (backends.py:81-85) displays command: cat $DATABASEURL — the literal…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The webcrawl() function in praisonaiagents/tools/webcrawltools.py accepts arbitrary URLs from AI agents with zero validation. No scheme allowlisting, hostname/IP blocklisting, or private network checks are applied before fetching. This allows an attacker (or prompt injection in crawled content) to force the agent to fetch cloud metadata endpoints, internal services, or local files via file:// URLs. Details The webcrawl() function at webcrawltools.py:182 accepts a URL string or list of URLs and passes them directly to HTTP clients without any SSRF protections: The crawlwithhttpx() fallback at line 133 makes the actual requests: The specific vulnerabilities are: 1. No URL scheme validation — http://, https://, file://, ftp://, gopher:// are all accepted 2. No hostname/IP blocklist — 169.254.169.254, 127.0.0.1, 10.x.x.x, 172.16.x.x, 192.168.x.x are all reachable 3. Redirect following enabled — httpx.Client(followredirects=True) allows redirect-based SSRF bypasses…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
readskillfile() in skilltools.py allows reading arbitrary files from the filesystem by accepting an unrestricted skillpath parameter. Unlike filetools.readfile which enforces workspace boundary confinement, and unlike runskillscript which requires critical-level approval, readskillfile has neither protection. An agent influenced by prompt injection can exfiltrate sensitive files without triggering any approval prompt. Details The vulnerability is a missing authorization check in readskillfile() at src/praisonai-agents/praisonaiagents/tools/skilltools.py:128. The function's path validation on line 163 only ensures filepath doesn't escape skillpath via directory traversal: The check on line 163 prevents filepath from containing ../ to escape skillpath, but skillpath itself is completely unrestricted — it can be any absolute directory on the filesystem. Compare with the protected equivalent in filetools.py:25-56: And compare with runskillscript (line 40) which requires…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The memory hooks executor in praisonaiagents passes a user-controlled command string directly to subprocess.run() with shell=True at src/praisonai-agents/praisonaiagents/memory/hooks.py lines 303 to 305. No sanitization, no shlex.quote(), no character filter, and no allowlist check exists anywhere in this file. Shell metacharacters including semicolons, pipes, ampersands, backticks, dollar-sign substitutions, and newlines are interpreted by /bin/sh before the intended command executes. Two independent attack surfaces exist. The first is via preruncommand and postruncommand hook event types registered through the hooks configuration. The second and more severe surface is the .praisonai/hooks.json lifecycle configuration, where hooks registered for events such as BEFORETOOL and AFTERTOOL fire automatically during agent operation. An agent that gains file-write access through prompt injection can overwrite .praisonai/hooks.json and have its payload execute silently at every…
Recommended action: Upgrade to 1.5.128 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The MultiAgentLedger and MultiAgentMonitor components in the provided code exhibit vulnerabilities that can lead to context leakage and arbitrary file operations. Specifically: 1. Memory State Leakage via Agent ID Collision: The MultiAgentLedger uses a dictionary to store ledgers by agent ID without enforcing uniqueness. This allows agents with the same ID to share ledger instances, leading to potential leakage of sensitive context data. 2. Path Traversal in MultiAgentMonitor: The MultiAgentMonitor constructs file paths by concatenating the basepath and agent ID without sanitization. This allows an attacker to escape the intended directory using path traversal sequences (e.g., ../), potentially leading to arbitrary file read/write. Details Vulnerability 1: Memory State Leakage - File: examples/context/12multiagentcontext.py:68 - Description: The MultiAgentLedger class uses a dictionary (self.ledgers) to store ledger instances keyed by agent ID. The getagentledger method…
Recommended action: Upgrade to 1.5.115 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 defaults to sandboxmode="sandbox", which runs user code in a subprocess wrapped with a restricted builtins dict and an AST-based blocklist. The AST blocklist embedded inside the subprocess wrapper (blockedattrs, line 143 of pythontools.py) contains only 11 attribute names — a strict subset of the 30+ names blocked in the direct-execution path. The four attributes that form a frame-traversal chain out of the sandbox are all absent from the subprocess list: | Attribute | In subprocess blockedattrs | In direct-mode blockedattrs | |---|---|---| | traceback | NO | YES | | tbframe | NO | YES | | fback | NO | YES | | fbuiltins | NO | YES | Chaining these attributes through a caught exception exposes the real Python builtins dict of the subprocess wrapper frame, from which exec can be retrieved and called under a non-blocked variable name — bypassing every remaining security layer. Tested and confirmed on praisonaiagents 1.5.113…
Recommended action: Upgrade to 1.5.115 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
FileTools.downloadfile() in praisonaiagents validates the destination path but performs no validation on the url parameter, passing it directly to httpx.stream() with followredirects=True. An attacker who controls the URL can reach any host accessible from the server including cloud metadata services and internal network services. Details filetools.py:259 (source) - filetools.py:296 (sink) PoC Impact On cloud infrastructure with IMDSv1 enabled, an attacker can retrieve IAM credentials via the EC2 metadata service and write them to disk for subsequent agent steps to exfiltrate. followredirects=True enables open-redirect chaining to bypass partial URL filters. Reachable via indirect prompt injection with no authentication required. Suggested Fix
Recommended action: Upgrade to 1.5.95 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
runpython() in praisonai constructs a shell command string by interpolating user-controlled code into python3 -c "<code" and passing it to subprocess.run(..., shell=True). The escaping logic only handles \ and ", leaving $() and backtick substitutions unescaped, allowing arbitrary OS command execution before Python is invoked. Details executecommand.py:290 (source) - executecommand.py:297 (hop) - executecommand.py:310 (sink) PoC Impact Any agent pipeline or API consumer that passes user or task-supplied content to runpython() is exposed to full OS command execution as the process user. The function is reachable via indirect prompt injection and the auto-generated Flask server deploys with AUTHENABLED = False by default when no token is configured.
Recommended action: Upgrade to 1.5.90 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
executecode() in praisonai-agents runs attacker-controlled Python inside a three-layer sandbox that can be fully bypassed by passing a str subclass with an overridden startswith() method to the safegetattr wrapper, achieving arbitrary OS command execution on the host. Details pythontools.py:20 (source) - pythontools.py:22 (guard bypass) - pythontools.py:161 (sink) PoC Impact Any user or agent pipeline running executecode() is exposed to full OS command execution as the process user. Deployments using bot.py, autonomymode.py, or botscli.py set PRAISONAIAUTOAPPROVE=true by default, meaning no human confirmation is required and the tool fires silently when triggered via indirect prompt injection.
Recommended action: Upgrade to 1.5.90 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.