
إثبات مفهوم ومختبر لـ Gitea Actions artifact v4 DoS: قراءة غير محدودة عبر io.ReadAll في parseProtobufBody تتيح لرمز المهمة إرسال أجسام CreateArtifact بحجم مفرط عبر POST.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-artifact-v4-readall
Gitea 1.27.3 - Gitea
job_summary.go يفرض بالفعل حدًا أقصى عند MaxJobSummarySize (1 MiB) باستخدام io.LimitReader. أما parseProtobufBody في artifact v4 فينفذ io.ReadAll(ctx.Req.Body) بدون أي حد. تمر CreateArtifact وFinalize وList وGet وDelete جميعها عبره. لا يكفي PAT عشوائي لمستخدم. تحتاج إلى job token قيد التشغيل. وظائف Fork-PR لا تزال NeedApproval على 1.27.3.
Job-summary تعلّم LimitReader. أما Artifact v4 فلم ينسخه. يمكن لوظيفة نشطة إرسال CreateArtifact بحجم 12 MiB وستقوم Gitea بتخزينه بالكامل.
| ID | لا يوجد CVE بعد |
| CWE | CWE-400 |
| CVSS | متوسط: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H |
| المنتج | Gitea |
| المتأثر | حتى v1.27.3 (146cc3e) مع تفعيل Actions |
| المصادقة | job token قيد التشغيل |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
من وظيفة Actions قيد التشغيل (مستودعه الخاص، أو fork-PR اجتاز بالفعل NeedApproval)، أرسل جسم CreateArtifact v4 بحجم عشوائي كبير وأجبر Gitea على تخزينه بالكامل. أما job-summary على نفس النسخة فيرفض بالفعل أي شيء يتجاوز 1 MiB.
هذا ضغط على الذاكرة في عملية Gitea. أثبت المختبر غياب الحد الأقصى (12 MiB -> 200). لم يقتل العملية. ليس RCE. ليس بدون مصادقة. PAT مسروق لمستخدم بدون وظيفة نشطة لا يصل إلى هذا المسار.
الخريطة المتبقية بعد موجة GHSA تضمنت معالجة أجسام Actions. وظائف Fork-PR لا تزال NeedApproval على 1.27.3، لذا هذا ليس تجاوزًا لـ fork-PR بدون مصادقة. نظرت في كيفية قراءة Actions API لأجسام الطلبات. job-summary لديه رقم. Artifact v4 ليس لديه.
قمت بتشغيل gitea/act_runner:0.2.13، وجهّزت workflow انتظار حتى يوجد job token، وأرسلت CreateArtifact بحجم 12 MiB. HTTP 200 ok بالإضافة إلى signedUploadUrl. ثم job-summary بحجم 8 MiB: 400 invalid summary. GET /api/v1/version لا يزال 200. بقيت Gitea تعمل. mem_limit في المختبر هو 1g. الجسم محدود بـ 12 MiB حتى لا يكون المضيف هو التجربة. منفّذ المضيف فقط. لا docker.sock.
المنعطفات الخاطئة مسجلة بالفعل: CreateArtifact بدون job token (401 ليس الثغرة)؛ قتل العملية / OOM (SUCCESS هو 12 MiB -> 200 بينما 8 MiB summary -> 400)؛ اعتبار signedUploadUrl بمثابة RCE؛ fork-PR بدون مصادقة؛ reverse shell. مسرحية.
cd lab
./run.sh
الهدف فقط http://127.0.0.1:18135. داخل compose يكون ROOT_URL هو http://gitea:3000/ حتى يتمكن الـ runner من التسجيل.
v4-create status=200 sent=12582912
v4-unbounded-readall=1
job-summary status=400 sent=8388608 invalid summary cap=MaxJobSummarySize=1048576
gitea-still-up status=200
SUCCESS GITEA-ARTIFACT-V4-READALL
غلّف parseProtobufBody بـ io.LimitReader عند حد بحجم proto، بنفس نمط MaxJobSummarySize. يجب أن يفشل CreateArtifact بحجم 12 MiB بنفس فئة الطريقة التي يفشل بها بالفعل job-summary بحجم 8 MiB.
GNU Affero GPL v3.0. راجع LICENSE. مختبر loopback فقط. بدون ضمان.