Summary
praisonaiagents: astgreprewrite rewrites arbitrary files without the @require_approval gate enforced on every sibling mutation tool
Target: PraisonAI (MervinPraison/PraisonAI)
Affected component: praisonaiagents/tools/ast_grep_tool.py, ast_grep_rewrite
Affected versions: master at ce97667156a116c50b4a3d1aa21e09f048903fda; reproduced against the current praisonaiagents PyPI release (praisonaiagents <= 1.6.52).
Tools in praisonaiagents/tools/ that modify on-disk state or run code are uniformly wrapped with @require_approval, which routes the call through an interactive approval flow before the body runs and fails closed, on denial (or with no approval backend configured) it raises PermissionError and the side effect does not occur. This is applied at every sibling mutation entry point:
| File | Line | Symbol | Risk level |
|---|---|---|---|
file_tools.py |
212 | copy_file |
high |
file_tools.py |
239 | move_file |
high |
file_tools.py |
266 | delete_file |
high |
edit_tools.py |
38 | EditTools.edit_file |
high |
edit_tools.py |
155 | edit_file |
high |
shell_tools.py |
32 | execute_command |
critical |
python_tools.py |
352 | execute_code |
critical |
ast_grep_tool.py:149 ast_grep_rewrite is structurally a sibling of these but has no decorator and no from ..approval import require_approval import. With dry_run=False (LLM-controllable), it builds sg --pattern <P> --rewrite <R> --lang <L> --update-all <path> (lines 204–211) and calls subprocess.run(cmd, ...) (line 215), modifying every file under path matching the pattern. There is no approval gate, no _validate_path workspace check, and no cwd= sandboxing. The function is registered as a top-level tool (__init__.py:182) and exposed via the code_intelligence built-in profile (profiles.py).
A secondary defect: on the dry_run=False path ast_grep_rewrite returns the literal string No changes made to the caller even when it modified files (the "No changes made" return at ast_grep_tool.py:230 is reached on this path), so an operator inspecting tool output sees no record that a write occurred.
Proof of concept
Single script, clean venv, praisonaiagents from PyPI, ast-grep CLI installed. PRAISONAI_AUTO_APPROVE is removed from the environment first, so no env-bypass is in play.
import os, tempfile, textwrap
os.environ.pop("PRAISONAI_AUTO_APPROVE", None)
workdir = tempfile.mkdtemp(prefix="poc-")
target = os.path.join(workdir, "target.py")
open(target, "w").write(textwrap.dedent("""
def safe_function(x):
return x + 1
def hello(name):
return 'hi ' + name
"""))
# Positive: undecorated tool rewrites the file.
from praisonaiagents.tools.ast_grep_tool import ast_grep_rewrite
ast_grep_rewrite(
pattern="def $FN($$$): return $$$",
replacement="def $FN($$$): import os; os.environ['POC_CANARY']='1'; return $$$",
lang="python", path=workdir, dry_run=False,
)
# Negative control: decorated sibling triggers the approval flow.
from praisonaiagents.tools.edit_tools import edit_file
edit_file(file_path=target, old_text="def hello(name):", new_text="def hello(name): # X")
Result, verified: ast_grep_rewrite rewrote target.py to contain the injected import os; os.environ['POC_CANARY']='1' payload, no approval prompt fired, and the call returned No changes made. The subsequent edit_file call in the same process rendered the Tool Approval Required panel and, on denial, raised PermissionError("Execution of edit_file denied: User denied") without modifying its target. Same process, same approval backend, the only difference is the missing decorator on ast_grep_rewrite.
Threat model
An LLM agent running locally whose tool surface includes ast_grep_rewrite (via the code_intelligence profile or direct import). Triggers: the operator asks the agent to refactor code, or prompt-injection in fetched docs / RAG context / any LLM-visible input steers the agent to call ast_grep_rewrite with attacker-chosen pattern, replacement, and path (the dry_run field is in the LLM-visible tool schema, so dry_run=False is requestable). The agent can then rewrite any file the host process can write, source trees, build configs, dotfiles, the agent's own source. With path="/" the rewrite is filesystem-wide. Because the rewrite injects arbitrary text, pointing it at a file that is later imported or executed turns this write primitive into code execution, the basis for the escalation noted in the CVSS line. No operator prompt and no audit record of the modification.
Coordinated disclosure
- Kai Aizen / SnailSploit,
[email protected], PGP on request.
Impact
The application does not perform an authorization check before performing a sensitive operation. Typical impact: unauthorized access to restricted functionality or data.
CVE-2026-55530 has a CVSS score of 6.1 (Medium). The vector is requires local access, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.6.58); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
--- a/praisonaiagents/tools/ast_grep_tool.py
+++ b/praisonaiagents/tools/ast_grep_tool.py
@@
from praisonaiagents._logging import get_logger
from typing import Optional, List
+from ..approval import require_approval
@@
+@require_approval(risk_level="high")
def ast_grep_rewrite(
pattern: str,
replacement: str,
high matches the file-modifying siblings; critical is defensible given the write→exec escalation. In the same patch: add a _validate_path workspace boundary check (cf. edit_tools.py:27); fix the No changes made return so it reflects actual modifications; apply the decorator to ast_grep_scan (ast_grep_tool.py:243) if it can write. ast_grep_search is read-only and can stay undecorated. A regression test asserting ast_grep_rewrite requires approval (alongside the other mutation tools) would have caught this at review time.
Frequently Asked Questions
- What is CVE-2026-55530? CVE-2026-55530 is a medium-severity missing authorization vulnerability in praisonaiagents (pip), affecting versions < 1.6.58. It is fixed in 1.6.58. The application does not perform an authorization check before performing a sensitive operation.
- How severe is CVE-2026-55530? CVE-2026-55530 has a CVSS score of 6.1 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of praisonaiagents are affected by CVE-2026-55530? praisonaiagents (pip) versions < 1.6.58 is affected.
- Is there a fix for CVE-2026-55530? Yes. CVE-2026-55530 is fixed in 1.6.58. Upgrade to this version or later.
- Is CVE-2026-55530 exploitable, and should I be worried? Whether CVE-2026-55530 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-55530 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-55530? Upgrade
praisonaiagentsto 1.6.58 or later.