CVE ID: CVE-2026-22038
产品: AutoGPT 平台(Stagehand 集成)
受影响版本: 所有版本,包括 autogpt-platform-beta-v0.6.45
修复版本: autogpt-platform-beta-v0.6.46
漏洞类型: CWE-532 — 将敏感信息插入日志文件
严重性: 高
报告人: Panuganti Siva Aditya (@sivaadityacoder)
报告日期: 2025 年 12 月 19 日
GitHub 安全公告: GHSA-rc89-6g7g-v5v7
AutoGPT 是一个开源平台,允许用户构建和运行自主 AI 代理。它包含一个 Stagehand 集成,用于连接浏览器自动化和 LLM 提供商,如 OpenAI、Anthropic 和 Groq。
在对 Stagehand 模块进行代码审查时,我注意到凭据对象被直接传递到 logger.info() 调用中。我追踪了每条日志语句,发现 .get_secret_value() 被内联调用——明确绕过了 Pydantic 提供的 SecretStr 保护。
存在漏洞的文件:
autogpt_platform/backend/backend/blocks/stagehand/blocks.py
三个模块受到影响,每个模块都有相同的模式:
StagehandObserveBlock(第 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(第 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(第 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()}"
)
为了确认可利用性,我使用有效凭据运行了每个 Stagehand 模块,并搜索了应用程序日志:
grep "secret:" /var/log/autogpt/application.log
输出确认真实的 API 密钥以明文形式出现:
[INFO] OBSERVE: Model credentials: ... secret: sk-proj-abc123xyz789...
[INFO] ACT: Model credentials: ... secret: sk-ant-api03-def456uvw...
[INFO] EXTRACT: Model credentials: ... secret: sk-1234567890abcdef...
AutoGPT 代码库正确使用了 Pydantic 的 SecretStr 类型来存储 API 密钥。当 SecretStr 对象被包含在 f-string 中或以正常方式打印时,它会显示为 **********——这种保护是有意设计的。
根本原因在于开发人员在 logger.info() 语句中直接调用了 .get_secret_value()。这会显式解包密钥并将原始字符串值传递给记录器,完全绕过了 SecretStr 的内置掩码功能。
日志级别为 INFO,这意味着这些语句在正常的生产环境中也会执行——而不仅仅是在本地调试会话中。每次这些模块之一使用凭据运行时,密钥都会被写入日志文件。
攻击场景:
secret:、sk-proj- 或 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"}]}'
暴露的凭据: Stagehand / Browserbase API 密钥、OpenAI API 密钥、Anthropic API 密钥、Groq API 密钥,以及 Stagehand 模块中配置的任何 LLM 提供商凭据。
autogpt-platform-beta-v0.6.46 中的补丁从 logger.info() 语句中移除了 .get_secret_value() 调用。
推荐方法 — 完全从日志中移除密钥:
# 修复前(存在漏洞):
logger.info(
f"OBSERVE: Model credentials: {model_credentials} for provider "
f"{model_credentials.provider} secret: {model_credentials.api_key.get_secret_value()}"
)
# 修复后(已修复):
logger.info(
f"OBSERVE: Model credentials for provider {model_credentials.provider} (API key redacted)"
)
替代方案 — 脱敏处理,保持日志结构完整:
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())}"
)
脱敏方法仅暴露前 4 个和后 4 个字符——足以识别使用了哪个密钥,而不会泄露完整密钥。
切勿在日志语句中调用 .get_secret_value()。 如果你的框架提供了密钥掩码类型(SecretStr、SecretBytes 等),请让它发挥其作用。在记录器中调用解包方法会完全破坏其目的。
INFO 是生产级别的日志记录。 调试风格的凭据转储绝不应达到 INFO 级别。如果你确实需要确认哪些凭据处于活动状态,只记录非敏感的元数据(提供商名称、密钥前缀、最后 4 个字符)。
日志文件是攻击面。 将它们视为任何其他敏感数据存储——限制访问、定期轮换并审计写入内容。聚合工具(Splunk、ELK、Datadog)通常具有广泛的读取权限,因此任何日志行中的密钥实际上也等同于这些系统中的密钥。
修复总是比漏洞本身更简单。 删除两行日志(或用脱敏版本替换)即可完全消除此暴露。因"临时调试日志"遗留到生产环境而产生的安全债务很常见,并且可以通过代码审查来预防。
SecretStr 保护是选择加入的,而非自动的。 开发人员必须理解,只有在没有人显式解包该值的情况下,保护才有效。代码审查应标记任何在认证路径之外使用 .get_secret_value() 的情况。
| 日期 | 事件 |
|---|---|
| 2025 年 12 月 19 日 | 通过 Huntr 和 GitHub 安全公告向 AutoGPT 维护者报告 |
| 2025–2026 年 | 维护者 Nicholas Tindle 确认了该报告 |
| 2026 年 4 月之前 | 在 autogpt-platform-beta-v0.6.46 中修复 |
| 2026 年 4 月 25 日 | 分配 CVE-2026-22038 |