
CVE-2026-22038에 대한 상세 분석: AutoGPT Stagehand 블록에서 API 키를 평문으로 기록하는 고심각도 취약점으로, 근본 원인, 영향 및 해결 방법을 포함합니다.
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 에이전트를 구축하고 실행할 수 있는 오픈소스 플랫폼입니다. 여기에는 OpenAI, Anthropic, Groq와 같은 브라우저 자동화 및 LLM 제공업체에 연결되는 Stagehand 통합이 포함됩니다.
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 코드베이스는 API 키에 Pydantic의 SecretStr 타입을 올바르게 사용합니다. 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 Security Advisory를 통해 AutoGPT 유지관리자에게 보고 |
| 2025–2026 | 유지관리자 Nicholas Tindle이 보고를 확인 |
| 2026년 4월 이전 | autogpt-platform-beta-v0.6.46에서 패치 |
| 2026년 4월 25일 | CVE-2026-22038 지정 |