
Análise detalhada da CVE-2026-22038, uma vulnerabilidade de alta gravidade nos blocos AutoGPT Stagehand que registra chaves de API em texto simples, incluindo causa raiz, impacto e remediação.
ID do CVE: CVE-2026-22038
Produto: Plataforma AutoGPT (integração Stagehand)
Versões Afetadas: Todas as versões até e incluindo autogpt-platform-beta-v0.6.45
Corrigido Em: autogpt-platform-beta-v0.6.46
Tipo de Vulnerabilidade: CWE-532 — Inserção de Informações Sensíveis em Arquivo de Log
Gravidade: Alta
Reportado Por: Panuganti Siva Aditya (@sivaadityacoder)
Data do Relatório: 19 de dezembro de 2025
Aviso do GitHub: GHSA-rc89-6g7g-v5v7
O AutoGPT é uma plataforma de código aberto que permite aos usuários criar e executar agentes de IA autônomos. Ela inclui uma integração Stagehand que se conecta a provedores de automação de navegador e LLM como OpenAI, Anthropic e Groq.
Durante uma revisão de código dos blocos Stagehand, notei que objetos de credenciais eram passados diretamente para chamadas logger.info(). Rastreei cada instrução de log e descobri que estava sendo chamado inline — contornando explicitamente a proteção que o Pydantic fornece.
.get_secret_value()SecretStrO arquivo vulnerável:
autogpt_platform/backend/backend/blocks/stagehand/blocks.py
Três blocos são afetados, cada um com o mesmo padrão:
StagehandObserveBlock (Linhas 185–188)
logger.info(f"OBSERVE: Stagehand credentials: {stagehand_credentials}")
logger.info(
f"OBSERVE: Model credentials: {model_credentials} for provider "
f"{model_credentials.provider} secret: {model_credentials.api_key.get_secret_value()}"
)
StagehandActBlock (Linhas 285–288)
logger.info(f"ACT: Stagehand credentials: {stagehand_credentials}")
logger.info(
f"ACT: Model credentials: {model_credentials} for provider "
f"{model_credentials.provider} secret: {model_credentials.api_key.get_secret_value()}"
)
StagehandExtractBlock (Linhas 373–376)
logger.info(f"EXTRACT: Stagehand credentials: {stagehand_credentials}")
logger.info(
f"EXTRACT: Model credentials: {model_credentials} for provider "
f"{model_credentials.provider} secret: {model_credentials.api_key.get_secret_value()}"
)
Para confirmar a explorabilidade, executei cada bloco Stagehand com credenciais válidas e pesquisei nos logs do aplicativo:
grep "secret:" /var/log/autogpt/application.log
A saída confirmou que chaves de API reais apareciam em texto puro:
[INFO] OBSERVE: Model credentials: ... secret: sk-proj-abc123xyz789...
[INFO] ACT: Model credentials: ... secret: sk-ant-api03-def456uvw...
[INFO] EXTRACT: Model credentials: ... secret: sk-1234567890abcdef...
O código do AutoGPT usa corretamente o tipo SecretStr do Pydantic para chaves de API. Quando um objeto SecretStr é incluído em uma f-string ou impresso normalmente, ele é renderizado como ********** — essa proteção é intencional.
A causa raiz é que os desenvolvedores chamaram .get_secret_value() diretamente dentro das instruções logger.info(). Isso explicitamente desembrulha o segredo e passa o valor bruto da string para o logger, contornando completamente a mascaramento integrado do SecretStr.
O nível de log é INFO, o que significa que essas instruções são executadas em ambientes normais de produção — não apenas em sessões locais de depuração. Toda vez que um desses blocos é executado com credenciais, o segredo é gravado no arquivo de log.
Cenário de ataque:
secret:, sk-proj- ou sk-ant-.curl https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer sk-proj-abc123xyz789..." \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4", "messages": [{"role": "user", "content": "test"}]}'
Credenciais expostas: chaves de API Stagehand / Browserbase, chaves de API OpenAI, chaves de API Anthropic, chaves de API Groq e quaisquer credenciais de provedor de LLM configuradas nos blocos Stagehand.
O patch em autogpt-platform-beta-v0.6.46 remove as chamadas .get_secret_value() das instruções logger.info().
Abordagem recomendada — remover o segredo do log completamente:
# Antes (vulnerável):
logger.info(
f"OBSERVE: Model credentials: {model_credentials} for provider "
f"{model_credentials.provider} secret: {model_credentials.api_key.get_secret_value()}"
)
# Depois (corrigido):
logger.info(
f"OBSERVE: Model credentials for provider {model_credentials.provider} (API key redacted)"
)
Alternativa — redigir, mantendo a estrutura do log intacta:
def redact_secret(value: str) -> str:
if len(value) <= 8:
return "***"
return f"{value[:4]}...{value[-4:]}"
logger.info(
f"OBSERVE: Model credentials for provider {model_credentials.provider} "
f"secret: {redact_secret(model_credentials.api_key.get_secret_value())}"
)
A abordagem de redação expõe apenas os primeiros e últimos 4 caracteres — o suficiente para identificar qual chave foi usada sem revelar o segredo completo.
Nunca chame .get_secret_value() em instruções de log. Se o seu framework fornece um tipo de mascaramento de segredos (SecretStr, SecretBytes, etc.), deixe-o fazer seu trabalho. Chamar o método de desembrulho dentro de um logger anula todo o propósito.
INFO é registro em nível de produção. Despejos de credenciais em estilo de depuração nunca devem chegar ao nível INFO. Se você realmente precisa confirmar quais credenciais estão ativas, registre apenas metadados não sensíveis (nome do provedor, prefixo da chave, últimos 4 caracteres).
Arquivos de log são uma superfície de ataque. Trate-os como qualquer outro armazenamento de dados sensíveis — restrinja o acesso, faça rotação e audite o que entra. Ferramentas de agregação (Splunk, ELK, Datadog) geralmente têm amplo acesso de leitura, então um segredo em qualquer linha de log é efetivamente um segredo nesses sistemas também.
A correção é sempre mais simples que o bug. Remover duas linhas de log (ou substituí-las por equivalentes redigidos) fecha completamente essa exposição. A dívida de segurança de "registro temporário de depuração" deixado em produção é comum e prevenível com revisão de código.
As proteções do SecretStr são opt-in, não automáticas. Os desenvolvedores devem entender que a proteção só se mantém enquanto ninguém desembrulha explicitamente o valor. A revisão de código deve sinalizar qualquer uso de .get_secret_value() fora do caminho de autenticação.
| Data | Evento |
|---|---|
| 19 de dezembro de 2025 | Reportado aos mantenedores do AutoGPT via Huntr e GitHub Security Advisory |
| 2025–2026 | O mantenedor Nicholas Tindle reconheceu o relatório |
| Antes de abril de 2026 | Corrigido em autogpt-platform-beta-v0.6.46 |
| 25 de abril de 2026 | CVE-2026-22038 atribuído |