CVE-2026-103956 - Loom for AWS - حرج - تجاوز المصادقة - مسؤول خارق غير مُصادق عليه عند عدم تكوين IdP
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cve-2026-103956-loom-unauth
Loom for AWS < 1.6.1 - AWS Labs
عندما يكون Cognito غير مضبوط ولا يوجد مزوّد هوية خارجي (IdP) نشط، فإن get_current_user يمنح كل طلب t-admin / g-admins-super. ويشمل ذلك الطلبات التي لا تحمل ترويسة Authorization. لذا فإن أي نشر جديد قبل إعداد IdP يُعدّ لوحة إدارة مفتوحة.
| المعرّف | CVE-2026-103956 |
| CWE | CWE-306 / CWE-1188 |
| CVSS | حرج: 10.0 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
| المنتج | Loom for AWS |
| المتأثر | < 1.6.1. إصدار المختبر المثبّت v1.6.0 (8c658d61). تم إصلاحه في v1.6.1 (ccad5665). |
| المصادقة | بدون مصادقة |
| الفئة | تجاوز المصادقة / مدير أعلى غير مُصادَق (ATO) |
| النطاق | عن بُعد (بدون مصادقة) |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
يمتلك المهاجم مستوى التحكم في الوكيل دون أي بيانات اعتماد.
GET /api/auth/me دون أي ترويسة يُرجع username=local-dev وsub=local والمجموعتين t-admin وg-admins-super. وكل نطاق في GROUP_SCOPES يأتي مع تلك الهوية.POST /api/mcp/servers غير المُصادَق يُرجع 201. وتقع MCP وA2A والوكلاء والذكريات والأمان والإعدادات وبيانات الاعتماد وتدقيق الإدارة خلف نفس الاعتمادية.GET /api/mcp/servers/{id}/export يتطلب admin:write. وفي هذا الإصدار المثبّت يُرجع oauth2_client_secret من SQLite. كما يذكر نص CVE إعادة كتابة سياسة دور IAM على أدوار الوكلاء المُدارة؛ وهذا المسار يتطلب AWS وهو خارج نطاق هذا المختبر المحلي (loopback).يتطلب v1.6.1 LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV بالإضافة إلى عميل loopback. الطلب نفسه يعيد 401 (No identity provider configured).
نشرت AWS CVE-2026-103956 مع GHSA-vgmj-998f-r8mp والنشرة 2026-124-AWS. ثبّتُّ awslabs/loom v1.6.0 (8c658d61) إلى جانب v1.6.1 (ccad5665) وشغّلت الواجهة الخلفية على SQLite مع عدم ضبط LOOM_COGNITO_USER_POOL_ID.
تتحقق دالة get_current_user في backend/app/dependencies/auth.py من متغيرات بيئة Cognito ومن صف IdP نشط. وعندما يكون كلاهما فارغًا: تُرجع UserInfo(sub="local", username="local-dev", groups=["t-admin", "g-admins-super"], scopes=ALL_SCOPES). ولا يُقرأ الرمز (token) إطلاقًا.
شغّلت FastAPI القياسي على loopback 127.0.0.1:18180 (v1.6.0) و18181 (v1.6.1). بلا واجهة أمامية. بلا AWS. كان طلب GET /api/auth/me غير المُصادَق على 1.6.0 يُرجع 200 مع تلك المجموعات. وكان طلب POST /api/mcp/servers غير المُصادَق مع oauth2_client_secret=CVE-2026-103956-WITNESS يُرجع 201. وأعاد GET /api/mcp/servers/1/export السرّ نفسه. أما على 1.6.1 فكان نفس الطلب /api/auth/me يُرجع 401.
SUCCESS CVE-2026-103956 me-http=200 me-user=local-dev me-sub=local me-groups=t-admin,g-admins-super mcp-create=201 export-has-secret=yes list-has-witness=yes patched-me-http=401 CVE-2026-103956-WITNESS
المسارات الخاطئة المسجّلة مسبقًا: تم تخطي public.ecr.aws/docker/library/python:3.13-slim لصالح Docker Hub python:3.13-slim؛ أول /health على v1.6.0 كان curl 52 بينما كان uvicorn مرتبطًا، ثم 200؛ مخطط إنشاء MCP طابق عند أول POST، دون إعادة محاولة 422. صدفة عكسية. مسرح. الأوراكل هو /api/auth/me بالإضافة إلى السر المُصدَّر.
cd lab
./run.sh
استهدف فقط http://127.0.0.1:18180 (v1.6.0) وhttp://127.0.0.1:18181 (v1.6.1). يقوم run.sh بعمل shallow-clone لتلك الوسوم، ويبني كلا الواجهتين الخلفيتين، ثم يفكك الحزمة. SQLite. لا توجد متغيرات بيئة Cognito. لا يوجد LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV على الخدمة المُرقّعة.
قم بالترقية إلى 1.6.1 أو أحدث. توصي AWS بـ 1.7.0 لمعالجة مشكلات SSRF/الرموز المميزة المشابهة. تجاوز 1.6.1 اختياري ومقتصر على loopback فقط. حتى ذلك الحين، أكمل إعداد Cognito أو مزوّد هوية خارجي قبل أن تصبح الواجهة الخلفية قابلة للوصول خارج loopback، وأبقِ LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV غير مضبوط على أي شيء يتم نشره.
backend/app/dependencies/auth.py (get_current_user)