sivaadityacoder/CVE-2026-22038
GitHub: sivaadityacoder/CVE-2026-22038
记录 CVE-2026-22038 漏洞细节的安全公告,揭示了 AutoGPT 平台因不当使用「.get_secret_value()」导致 API 密钥明文记录在日志中的问题及修复方案。
Stars: 0 | Forks: 0
# CVE-2026-22038 — AutoGPT Stagehand Blocks 日志 API 密钥明文泄露
**CVE ID:** CVE-2026-22038
**产品:** AutoGPT Platform (Stagehand integration)
**受影响版本:** 所有版本,包括及之前的 `autogpt-platform-beta-v0.6.45`
**修复版本:** `autogpt-platform-beta-v0.6.46`
**漏洞类型:** CWE-532 — 敏感信息写入日志文件
**严重程度:** 高
**报告人:** Panuganti Siva Aditya ([@sivaadityacoder](https://github.com/sivaadityacoder))
**报告日期:** 2025 年 12 月 19 日
**GitHub 安全公告:** [GHSA-rc89-6g7g-v5v7](https://github.com/Significant-Gravitas/AutoGPT/security/advisories/GHSA-rc89-6g7g-v5v7)
## 我的方法
AutoGPT 是一个开源平台,允许用户构建和运行自主的 AI agents。它包含一个 Stagehand 集成,可连接到浏览器自动化以及 OpenAI、Anthropic 和 Groq 等 LLM 提供商。
在对 Stagehand blocks 进行代码审查时,我注意到凭据对象被直接传递到了 `logger.info()` 调用中。我追踪了每条日志语句,发现 `.get_secret_value()` 在行内被调用——这明确绕过了 Pydantic 提供的 `SecretStr` 保护。
**易受攻击的文件:**
```
autogpt_platform/backend/backend/blocks/stagehand/blocks.py
```
三个 blocks 受到影响,每个都具有相同的模式:
**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 block,并搜索了应用程序日志:
```
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()`。这明确地解开了秘密封装,并将原始字符串值传递给 logger,完全绕过了 `SecretStr` 内置的掩码机制。
日志级别是 `INFO`,这意味着这些语句会在正常的生产环境中执行——而不仅仅是在本地调试会话中。每次运行这些带有凭据的 blocks 时,秘密都会被写入日志文件。
## 影响
- **凭据盗窃** — 明文 API 密钥停留在日志文件中,任何拥有日志访问权限的人都可以获取
- **经济损失** — 被盗的密钥会被用来进行昂贵的 API 调用,费用由受害者承担
- **数据访问** — 被盗的凭据可能会授权访问受害者在这些服务中的数据
- **配额耗尽** — 攻击者可以故意耗尽速率限制以拒绝服务
- **漫长的暴露窗口** — 日志文件通常会保留 30–90 天,因此使用一次的密钥可能会暴露数月之久
- **合规性问题** — 记录秘密违反了 PCI-DSS、SOC 2 和 GDPR 要求
**攻击场景:**
1. 攻击者通过配置错误的聚合系统(Splunk、ELK、Datadog、CloudWatch)、受损的监控账户或过高的内部权限,获得了对日志文件的读取权限。
2. 他们搜索日志中的模式,例如 `secret:`、`sk-proj-` 或 `sk-ant-`。
3. 他们从日志输出中提取真实的 API 密钥。
4. 他们验证密钥:
```
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"}]}'
```
5. 拥有有效密钥后,他们可以进行 API 调用、耗尽配额或访问受害者的数据。
**暴露的凭据:** Stagehand / Browserbase API 密钥、OpenAI API 密钥、Anthropic API 密钥、Groq API 密钥,以及在 Stagehand blocks 中配置的任何 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 个字符——足以识别使用了哪个密钥,而不会泄露完整的秘密。
## 关键要点
1. **切勿在日志语句中调用 `.get_secret_value()`。** 如果您的框架为您提供了一个秘密掩码类型(`SecretStr`、`SecretBytes` 等),请让它发挥作用。在 logger 中调用解封方法会完全违背其初衷。
2. **`INFO` 是生产级别的日志记录。** 凭据的调试式转储永远不应到达 `INFO` 级别。如果您确实需要确认哪些凭据处于活动状态,请仅记录非敏感的元数据(提供商名称、密钥前缀、最后 4 个字符)。
3. **日志文件是攻击面。** 像对待任何其他敏感数据存储一样对待它们——限制访问、轮换它们并审计写入的内容。聚合工具(Splunk、ELK、Datadog)通常具有广泛的读取权限,因此任何日志行中的秘密实际上也是那些系统中的秘密。
4. **修复总是比 Bug 更简单。** 删除两行日志(或用脱敏的等效内容替换它们)可以完全消除这种暴露。生产环境中遗留下来的“临时调试日志”造成的安全债务很常见,可以通过代码审查来预防。
5. **`SecretStr` 的保护是选择加入的,而不是自动的。** 开发人员必须明白,只要没有人明确地解封该值,这种保护就有效。代码审查应该标记任何在身份验证路径之外使用 `.get_secret_value()` 的情况。
## 时间线
| 日期 | 事件 |
|------|-------|
| 2025 年 12 月 19 日 | 通过 Huntr 和 GitHub Security Advisory 报告给 AutoGPT 维护者 |
| 2025–2026 | 维护者 Nicholas Tindle 确认了报告 |
| 2026 年 4 月之前 | 在 `autogpt-platform-beta-v0.6.46` 中修复 |
| 2026 年 4 月 25 日 | 分配了 CVE-2026-22038 |
## 参考
- [GitHub 安全公告 GHSA-rc89-6g7g-v5v7](https://github.com/Significant-Gravitas/AutoGPT/security/advisories/GHSA-rc89-6g7g-v5v7)
- [CWE-532:敏感信息写入日志文件](https://cwe.mitre.org/data/definitions/532.html)
- [OWASP 日志记录备忘单](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)
- [Trickest CVE 数据库条目](https://github.com/trickest/cve/blob/main/2026/CVE-2026-22038.md)
标签:AI智能体, Anthropic, API密钥泄露, AutoGPT, CIS基准, CVE-2026-22038, CWE-532, DLL 劫持, GitHub安全通告, LLM, OpenAI, Pydantic, SecretStr, Stagehand, Unmanaged PE, 内存规避, 大语言模型, 实时处理, 数据泄露, 日志安全, 浏览器自动化, 漏洞分析, 路径探测, 逆向工具