
تحليل تفصيلي لـ CVE-2026-22038، ثغرة أمنية عالية الخطورة في كتل AutoGPT Stagehand تسجّل مفاتيح API كنص عادي، بما في ذلك السبب الجذري والتأثير والمعالجة.
معرف CVE: CVE-2026-22038
المنتج: منصة AutoGPT (تكامل Stagehand)
الإصدارات المتأثرة: جميع الإصدارات حتى autogpt-platform-beta-v0.6.45 وما يشملها
تم التصحيح في: autogpt-platform-beta-v0.6.46
نوع الثغرة: CWE-532 — إدراج معلومات حساسة في ملف السجل
الخطورة: عالية
أبلغ عنها: Panuganti Siva Aditya (@sivaadityacoder)
تاريخ الإبلاغ: 19 ديسمبر 2025
استشارة GitHub: GHSA-rc89-6g7g-v5v7
AutoGPT هي منصة مفتوحة المصدر تتيح للمستخدمين بناء وتشغيل وكلاء ذكاء اصطناعي مستقلين. تتضمن تكامل Stagehand الذي يتصل بأتمتة المتصفح ومزودي نماذج اللغة الكبيرة مثل 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 بشكل صحيح نوع SecretStr من Pydantic لمفاتيح API. عندما يتم تضمين كائن SecretStr في سلسلة f-string أو طباعته بشكل عادي، فإنه يُعرض كـ ********** — هذه الحماية مقصودة.
السبب الجذري هو أن المطورين استدعوا .get_secret_value() مباشرة داخل عبارات logger.info(). هذا يفك تغليف السر بشكل صريح ويمرر قيمة السلسلة الخام إلى المسجل، متجاوزًا تمامًا آلية الإخفاء المدمجة في 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"}]}'
بيانات الاعتماد المكشوفة: مفاتيح API الخاصة بـ Stagehand / Browserbase، ومفاتيح API الخاصة بـ OpenAI، ومفاتيح API الخاصة بـ Anthropic، ومفاتيح API الخاصة بـ Groq، وأي بيانات اعتماد لمزود نماذج لغة كبيرة تم تكوينها في كتل Stagehand.
يزيل التصحيح في autogpt-platform-beta-v0.6.46 استدعاءات .get_secret_value() من عبارات logger.info().
النهج الموصى به — إزالة السر من السجل تمامًا:
# قبل (معرض للخطر):
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 أحرف — وهو ما يكفي لتحديد المفتاح المستخدم دون كشف السر الكامل.
لا تستدعِ .get_secret_value() أبدًا في عبارات السجل. إذا كان إطار العمل الخاص بك يوفر نوعًا لإخفاء الأسرار (SecretStr أو SecretBytes أو غيرهما)، فدعه يقوم بعمله. استدعاء طريقة فك التغليف داخل مسجل يبطل الغرض بالكامل.
INFO هو مستوى تسجيل للإنتاج. يجب ألا تصل تفريغات بيانات الاعتماد بنمط التصحيح إلى مستوى INFO أبدًا. إذا كنت تحتاج حقًا لتأكيد بيانات الاعتماد النشطة، فسجّل فقط البيانات الوصفية غير الحساسة (اسم المزود، بادئة المفتاح، آخر 4 أحرف).
ملفات السجلات هي سطح هجوم. تعامل معها كأي مخزن بيانات حساس آخر — قيّد الوصول، ودوّرها، ودقق ما يدخل إليها. غالبًا ما تمتلك أدوات التجميع (Splunk وELK وDatadog) وصول قراءة واسعًا، لذا فإن السر في أي سطر سجل هو فعليًا سر في تلك الأنظمة أيضًا.
الإصلاح دائمًا أبسط من الثغرة. إزالة سطري تسجيل (أو استبدالهما بمعادلين مخفيين) يغلق هذا التعرض تمامًا. الديون الأمنية الناتجة عن "تسجيل تصحيح مؤقت" تُترك في الإنتاج شائعة ويمكن منعها بمراجعة الكود.
حمايات SecretStr اختيارية وليست تلقائية. يجب على المطورين فهم أن الحماية تصمد فقط طالما لم يقم أحد بفك تغليف القيمة بشكل صريح. يجب أن تعلّم مراجعة الكود أي استخدام لـ .get_secret_value() خارج مسار المصادقة.
| التاريخ | الحدث |
|---|---|
| 19 ديسمبر 2025 | تم الإبلاغ إلى القائمين على AutoGPT عبر Huntr واستشارة أمان GitHub |
| 2025–2026 | أقر القائم على الصيانة Nicholas Tindle بالتقرير |
| قبل أبريل 2026 | تم التصحيح في autogpt-platform-beta-v0.6.46 |
| 25 أبريل 2026 | تم تعيين CVE-2026-22038 |