### Resumo As embrulhas de ferramentas `praisonai.code` do PraisonAI (exportadas como `CODE_TOOLS` para agentes) expõem uma configuração `workspace` que o módulo em si trata como um caminho- percurso **limite de segurança** — `read_file`, `write_file`, `apply_diff` e `search_replace` chamam explicitamente `is_path_inside_directory()` e retornam `"... está fora do espaço de trabalho"` em violações. Esse limite é forçado ** insatisfatório e inconsistente**: 1. O ajudante de contenção usa `os.path.abspath()`, não `realpath()`/ `Path.resolve()`. Um link simbólico localizado ** dentro** do espaço de trabalho cujo alvo é ** fora** tem um `abspath()` que ainda está dentro do espaço de trabalho, então ele passa a verificação enquanto `open()` segue o link. Isto evita ler, escrever, aplicar_diff e search_place (CWE- 59 ). 2. `list_files()` resolve ` caminho ' contra o espaço de trabalho, mas ** nunca** chama o ajudante de contenção — `.../ ' e os caminhos absolutos escapam diretamente (CWE-- 22 ). 3. `execute_command()` toma um argumento `workspace` documentado "para validação de segurança" mas executa a verificação de contenção ** não** `cwd`; `code_execute_command()` resolve um `cwd` relativo contra o espaço de trabalho e também nunca o valida (e nunca passa `workspace` para o ajudante de baixo nível). Um comando relativo `cwd="../outside' executa comandos de fora do espaço de trabalho (CWE- 22 ). Um atacante que pode influenciar um agente que tem estas ferramentas anexadas (injeção indireta, injeção indireta ou um agente exposto ao servidor) pode ler, sobrescrever, listar e executar fora do espaço de trabalho configurado, limitado apenas pelas permissões do sistema de arquivos do usuário do processo.
### 1. Ajuda de contenção sem som (conexão de ligação simbólica — CWE- 59 ) ```python # src/praisonai/praisonai/code/utils/file_utils.py — is_path_inside_directory() abs_file = os.path.abspath(file_path) # NÃO resolve os links simbólicos abs_dir = os.path.abspath(directory) se não abs_dir.endswith(os.sep): abs_dir += os.sep retorna abs_file.startswith(abs_dir) ou abs_file == abs_dir.rstrip(os.sep) ```.
`read_file`/`write_file`/`apply_diff`/`search_replace` chama isto com o espaço de trabalho configurado (por exemplo, `read_file.py`: `# Verificação de segurança - garantir que o caminho está dentro do espaço de trabalho`). Como `abspath()` não canoniza os links simbólicos, um link em `WORKSPACE/link_to_secret.txt` → `/outside/secret.txt` tem `abspath` `WORKSPACE/link_to_secret.txt` (inside) e passa, enquanto `open()` o segue para o alvo real externo. ### 2. `list_files()` não tem verificação de contenção (CWE- 22 ). ```python # src/praisonai/praisonai/code/tools/list_files.py se o espaço de trabalho e não os.path.isabs(path): abs_path = os.path.abspath(os.path.join(workspace, path)) #../ colapsa fora do espaço de trabalho: abs_path = os.path.abspath(path) # o caminho absoluto usado como- é #... os.path.isdir(abs_path) em seguida, listado. is_path_inside_directory() NUNCA é chamado. ```.
### 3. `execute_command()` nunca valida ` cwd` (CWE- 22 ). ```python # src/praisonai/praisonai/code/tools/execute_command.py — doc do espaço de trabalho: "para validação de segurança" se cwd: se o espaço de trabalho e não os.path.isabs(cwd): work_dir = os.path.abspath(os.path.join(workspace, cwd)) #../ escapa; nenhuma outra verificação de contenção: work_dir = os.path.abspath(cwd) # subprocess.run(args, cwd=work_dir,...) # no is_path_inside_directory() em qualquer lugar ```` ```python # src/praisonai/praisonai/code/agent_tools.py — code_execute_command() se work_dir e _workspace_root e não os.path.isabs(work_dir): work_dir = os.path.join(_workspace_root, work_dir) # se junta, nunca valida resultado = _execute_command(command=command, cwd=work_dir, timeout= 120 ) # espaço de trabalho nem mesmo passou em ```.
Nota: `execute_command` rejeita `shell=True` e executa `shlex.split(command)` via `subprocess.run` (sem shell), por isso os metacaracters de shell (`&&`, `>`, tubos) não funcionam — mas qualquer binário ainda funciona com o atacante- escolhido argv ** do cwd** escape, o que é suficiente para ler/escrever fora do espaço de trabalho. ### O espaço de trabalho é um limite pretendido (pre-impedido "por design"). O módulo afirma este controle em si: `read_file.py` "Security check - assegure que o caminho está dentro do espaço de trabalho"; `write_file.py` "o espaço de trabalho por default é cwd para que os caminhos relativos não possam escapar"; `is_path_inside_directory` docstring (prevenção do caminho transversal); `execute_command` `workspace` param "para validação de segurança". O erro é que o controle afirmado é umsound (abspath vs realpath) e não aplicado ao cwd `list_files`/`execute_command`.
Apenas com ajustes de temperatura locais e autónomos; nenhuma rede, nenhum comando não confiável. As ferramentas de agente real `praisonai.code` foram chamadas. ```` espaço de trabalho = / tmp/.../ espaço de trabalho fora = / tmp/.../ fora [ 1 ] plana de base../ ler -> BLOQUEADO: "Path '../outside/secret.txt' está fora do espaço de trabalho" [ 2 ] link simbólico lido (in-WS link) -> SUCESSO: retornou "SECRET_OUTSIDE_WORKSPACE" [ 3 ] gravação de links simbólicos (em- WS link) -> SUCESSO: arquivo externo agora contém "OVERWRITTEN_VIA_SYMLINK" [ 4 ] code_list_files("../outside") -> SUCESSO: "Conteúdo de../outside: ї secret.txt" [ 5 ] code_execute_command(cwd="../outside","pwd") -> SUCESSO: stdout "/ tmp/.../outside" [ 6 ] code_execute_command(cwd="../outside", python 3 -c open('planted.txt','w')...) -> SUCESSO: novo arquivo criado para fora do espaço de trabalho, "PWNETD_OUTSIDE_WORKSPACE" ```.
Passos 2 – 6 cada cruzamento do limite do espaço de trabalho configurado; passo 1 mostra a guarda simples- `../ ` que o link simbólico e vetores não- scoped bypass. - **Confidencialidade**: ler arquivos fora do espaço de trabalho (link simbólico no espaço de trabalho; ou listar/ enumerar dirs externos via `list_files`). - **Integridade**: sobrescrever arquivos externos via link simbólico; criar/ modificar arquivos fora do espaço de trabalho via `execute_command` executando em um cwd escapado. - **Contorno de execução**: executar binários arbitrários disponíveis (controlados por argv) a partir de um diretório fora do espaço de trabalho. Atacado pelas permissões do usuário do processo. Em um agente de código ou agente exposto ao servidor que processa entradas não confiáveis, isso expõe arquivos secretos / junto ao projeto / host e quebra a integridade do projeto- limite garante a configuração do espaço de trabalho anunciado.
- Substituir `is_path_inside_directory()` por um `realpath()` / `Path.resolve()`- baseado na verificação de contenção, e comparar com `os.path.commonpath()` em vez de `startswith`. - Aplicar que verifique consistentemente para cada caminho de arquivo, caminho de diretório, caminho de backup, diretório de diff/search-replace, **e diretório de trabalho de comandos, após canonização completa (resolver o alvo real do link simbólico, não o caminho de link). - `list_files()`: rejeita os caminhos absolutos e `./` escapa quando `workspace' está definido. - `execute_command()`: validar a contenção `cwd` quando `workspace` está definido; `code_execute_command()` deve passar `_workspace_root` ao ajudante de baixo nível ou validar- se mesmo. - Testes de regressão: leia/es de leia/re `list_files("../outside", workspace=...)`; `execute_command(cwd="../outside", workspace=...)`; caminhos externos absolutos com um conjunto de espaços de trabalho. Registro de aconselhamento: GHSA-ch 89 - h 4 r 2 - c 8 f 8. Identificadores relacionados: CVE- 2026 - 55540.
Tempo: GitHub Advisory Database publicou este registro em 2026 - 08 - 25 T 14: 54: 56.000 Z e lista a sua última modificação como 2026 - 08 - 25 T 14: 54: 56.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:L.
Software afetado e informações de versão: pacote PyPI PraisonAI — ECOSISTEM: introduzido 0, corrigido 4.6.58. Classificação e evidência: identificadores de fraqueza CWE- 22. O registro contém 4 suporte de referências nestes tipos: WEB, PACKAGE.