
GitLab - عالي - استيراد Gitea عبر HTTPS SSRF - إسقاط دبوس UrlBlocker
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitlab-gitea-import-ssrf
المقال التقني: https://abraxaslabs.tech/research/gitlab-gitea-import-ssrf
GitLab CE 19.4.1 - GitLab Inc.
استيراد Gitea يستدعي UrlBlocker.validate! مرة واحدة، ثم في حالة https يتخلص من URI المثبَّت على عنوان IP ويسلّم Faraday اسم المضيف الأصلي. أما Octokit UrlValidation فيتحقق مرة أخرى ولا يعيد كتابة env[:url]. أعد ربط الاسم بين هذين الاستدعاءين وستقوم GitLab بعمل GET إلى loopback كما لو كان Gitea. تعود بيانات JSON الخاصة بقائمة المستودعات عبر GET /import/gitea/status.json. عمليات استيراد HTTP تحتفظ بالتثبيت. أما https://127.0.0.1 المباشر فمحظور.
مستخدم مسجّل الدخول يمكنه فتح استيراد Gitea على مساحته الشخصية يمكنه جعل GitLab يجلب مضيفًا يعيد ربطه إلى loopback، ويحصل على محتوى الاستجابة.
| المعرّف | لا يوجد CVE بعد |
| CWE | CWE-918، CWE-367 |
| CVSS | عالٍ: 7.7 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N |
| المنتج | GitLab CE |
| المتأثر | 19.4.1-ce.0 (26212baacadb على شجرة v19.4.1-ee) |
| المصادقة | مستخدم موثَّق، استيراد Gitea، مساحة شخصية |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
عيّن عنوان مضيف Gitea إلى https://<name-they-control>/. يسمح UrlBlocker بأول سجل A عام. يحتفظ client_options الخاص بـ HTTPS باسم المضيف ذلك. أعد الربط إلى 127.0.0.1. يقوم Faraday بعمل GET إلى المستقبِل على loopback الخاص بعامل GitLab. حقل provider_repos في status.json هو ما أعاده المستقبِل.
في تثبيت omnibus الشامل يشمل ذلك Workhorse وPuma وعوامل التصدير وأي شيء آخر يستمع على العامل. ليس RCE على المضيف. وليس بدون مصادقة. يبقى عنوان مضيف HTTP على عنوان IP المثبَّت.
نفس المنتج، بقايا شقيقة: جلب Gitaly يحذف resolved_address، webhook 0.0.0.0/8.
قرأت ملاحظات التصحيح الصادرة في 23 سبتمبر 2026 للإصدارات 19.4.1 / 19.3.3 / 19.2.7 أولًا، ثم شجرة v19.4.1-ee. ثغرة RCE عبر تعبير نمطي في CI، وXSS في فرق MR، وقراءة file.path في Workhorse كلها مغلقة على هذا التثبيت. أما SSRF في الاستيراد فلم يكن مكتملًا.
Import::GiteaController#client_options هو البقايا:
host: verified_url.scheme == 'https' ? provider_url : verified_url.to_s,
HTTP يستخدم verified_url (IP). HTTPS يستخدم provider_url (الاسم الذي كتبه المستخدم). LegacyGithubImport::Client يبني api_endpoint الخاص بـ Octokit من ذلك المضيف. Gitlab::Octokit::UrlValidation يستدعي validate! ثم @app.call(env) دون أي إعادة كتابة.
أقمت نسخة gitlab/gitlab-ce:19.4.1-ce.0 القياسية. الطلبات المحلية معطّلة. شهادة CA المخبرية في /etc/gitlab/trusted-certs لأن ssl.verify في Faraday مضبوط على true. DNS لـ gitea.lab: عمليات البحث 1-2 تُرجع 1.1.1.1، وعمليات البحث اللاحقة تُرجع 127.0.0.1. الـ catcher يتشارك netns الخاص بـ GitLab على :443. أعاد GET /import/gitea/status.json قيمة provider_repos باسم GITLAB-GITEA-IMPORT-SSRF-WITNESS. سجل الـ catcher: GET /api/v1/user/repos peer=127.0.0.1 host=gitea.lab.
https://127.0.0.1/ مباشرةً: "Specified URL cannot be used". أما HTTP http://gitea.lab/ فبقي على التثبيت ولم يُرجع الشاهد.
أخطاء مسجّلة سابقاً: /users/sign_in مع Accept: application/json يُرجع 404 (أما HTML فيُرجع 200)؛ كلمة مرور البذرة CveLabRoot9! مرفوضة لأنها تحتوي على root؛ ربط CA بـ ro يُنتج EROFS بعد أن يربط إعادة التهيئة الملف؛ اعتماد أول نتيجتين ثم loopback في البحث الثاني يجعل UrlValidation يحجب قبل أن يتصل Faraday. نمط الأزواج (فردي عام، زوجي loopback) هو ما نجح. reverse shell. مسرح. الـ oracle هو الشاهد في status.json بالإضافة إلى peer الخاص بالـ catcher.
cd lab
./run.sh
استهدف فقط http://127.0.0.1:18400. يحتاج GitLab CE إلى عدة غيغابايت من الذاكرة العشوائية. الإقلاع الأول بطيء. مختبر مُصرَّح به فقط.
status.json status=200 ... provider_repos ... GITLAB-GITEA-IMPORT-SSRF-WITNESS
catcher GET /api/v1/user/repos peer=127.0.0.1 host=gitea.lab status=200 witness=True
negative-a https://127.0.0.1 blocked
negative-b http://gitea.lab no-witness
SUCCESS GITLAB-GITEA-IMPORT-SSRF status.json mode=pairs http=200 GITLAB-GITEA-IMPORT-SSRF-WITNESS
def client_options
verified_url, provider_hostname = verify_blocked_uri
{
host: verified_url.scheme == 'https' ? provider_url : verified_url.to_s,
api_version: 'v1',
hostname: provider_hostname
}
end
استخدم verified_url.to_s لـ https بالطريقة نفسها التي يتعامل بها HTTP بالفعل. أعد كتابة env[:url] في UrlValidation الخاص بـ Octokit إلى عنوان IP المثبّت.
gitea_controller.rb · legacy_github_import/client.rb · octokit/url_validation.rbGNU Affero GPL v3.0. راجع LICENSE. للاستخدام في مختبر loopback فقط. دون أي ضمان.