PraisonAI: Code Injection via f-string Interpolation in Deploy API Server Generation
What fixes it
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Summary
The deploy/api.py module generates Python server code by directly interpolating the agents_file parameter into an f-string that is then written to a file and executed via subprocess.Popen(). An attacker who controls the agents_file value (via CLI argument, configuration, or upstream API) can inject arbitrary Python code.
Details
src/praisonai/praisonai/deploy/api.py (line 80):
code = f'''...
praisonai = PraisonAI(agent_file="{agents_file}")
...
"agent_file": "{agents_file}"
...'''The generated code is then executed (line 190):
subprocess.Popen(['python', server_file])
agents_file is never sanitized or validated. A malicious value breaks out of the string context:
agents_file = '"); import os; os.system("id"); #'
# Generated code becomes:
# praisonai = PraisonAI(agent_file=""); import os; os.system("id"); #")The same pattern exists in deploy/docker.py (line 33) for Dockerfile generation.
PoC
# The injection:
agents_file = '"); import os; os.system("id"); #'
# What the generated code looks like:
template = f'praisonai = PraisonAI(agent_file="{agents_file}")'
print(template)
# Output: praisonai = PraisonAI(agent_file=""); import os; os.system("id"); #")Impact
- Arbitrary code execution on the machine running the deploy command
- Supply chain risk if
agents_filecomes from a configuration file or CI/CD pipeline
Text from GitHub Advisory Database
Affected versions 53
- PraisonAI, pip<= 4.6.77GitHub
- PraisonAIaffected: < 4.6.78CVE List
- praisonai, PyPIfrom first release, fixed in 4.6.78OSV
- praisonai, PyPI0.0.1OSV
- praisonai, PyPI0.0.10OSV
- praisonai, PyPI0.0.11OSV
- praisonai, PyPI0.0.12OSV
- praisonai, PyPI0.0.13OSV
- praisonai, PyPI0.0.14OSV
- praisonai, PyPI0.0.15OSV
- praisonai, PyPI0.0.16OSV
- praisonai, PyPI0.0.17OSV
- praisonai, PyPI0.0.18OSV
- praisonai, PyPI0.0.19OSV
- praisonai, PyPI0.0.2OSV
- praisonai, PyPI0.0.20OSV
- praisonai, PyPI0.0.21OSV
- praisonai, PyPI0.0.22OSV
- praisonai, PyPI0.0.23OSV
- praisonai, PyPI0.0.24OSV
- praisonai, PyPI0.0.25OSV
- praisonai, PyPI0.0.26OSV
- praisonai, PyPI0.0.27OSV
- praisonai, PyPI0.0.28OSV
- praisonai, PyPI0.0.29OSV
- praisonai, PyPI0.0.3OSV
- praisonai, PyPI0.0.30OSV
- praisonai, PyPI0.0.31OSV
- praisonai, PyPI0.0.32OSV
- praisonai, PyPI0.0.33OSV
- praisonai, PyPI0.0.34OSV
- praisonai, PyPI0.0.35OSV
- praisonai, PyPI0.0.36OSV
- praisonai, PyPI0.0.37OSV
- praisonai, PyPI0.0.38OSV
- praisonai, PyPI0.0.39OSV
- praisonai, PyPI0.0.4OSV
- praisonai, PyPI0.0.40OSV
- praisonai, PyPI0.0.41OSV
- praisonai, PyPI0.0.42OSV
- praisonai, PyPI0.0.43OSV
- praisonai, PyPI0.0.44OSV
- praisonai, PyPI0.0.45OSV
- praisonai, PyPI0.0.46OSV
- praisonai, PyPI0.0.47OSV
- praisonai, PyPI0.0.48OSV
- praisonai, PyPI0.0.49OSV
- praisonai, PyPI0.0.5OSV
- praisonai, PyPI0.0.50OSV
- praisonai, PyPI0.0.52OSV
- praisonai, PyPI0.0.53OSV
- praisonai, PyPI0.0.54OSV
- praisonai, PyPI0.0.55OSV