القائمة الرئيسية

الصفحات

سد ثغرات الروابط على "Visual Studio Code"

Securing Link Gaps on Visual Studio Code،Securing،Link Gaps on Visual Studio Code،Developer Tools: Argument Injection in Visual Studio Code،Plugging Link Gaps،Visual Studio Code،Plugging Link Gaps on "Visual Studio Code"،Securing Developer Tools: Argument Injection in Visual Studio Code،سد ثغرات الروابط على Visual Studio Code،سد ثغرات الروابط على "Visual Studio Code"،تأمين أدوات المطور،حقن الوسيطة في Visual Studio Code،تأمين أدوات المطور: حقن الوسيطة في Visual Studio Code،




سد ثغرات الروابط على "Visual Studio Code"



توضح هذه المقالة كيف يمكن أن تؤدي ثغرة أمنية في أحد معالجات عنوان
 URL لـ VS Code إلى تنفيذ أوامر عشوائية على مضيف الضحية.
تعد سلامة هذه التطبيقات أمرًا ضروريًا لمنع المهاجمين من تعريض الكمبيوتر 
الذي يعمل عليه المطورون للخطر ، حيث يمكنهم استخدام هذا الوصول للحصول 
على معلومات حساسة ، وتغيير كود المصدر ، ومزيد من التمحور في الشبكة الداخلية للشركة.
هذه المرة ، تغوص أنا وفريقي في ثغرة أمنية جديدة حددتها في أحد أكثر IDEs شيوعًا:
 Visual Studio Code.
 لقد سمح للمهاجمين بصياغة روابط ضارة من شأنها ، بمجرد التفاعل معها ،
 خداع IDE لتنفيذ أوامر غير مقصودة على كمبيوتر الضحية. من خلال الإبلاغ
 عن المشكلة إلى Microsoft ، التي قامت بتصحيحها بسرعة ، ساعد باحثونا في تأمين النظام البيئي للمطورين. 


تأثير Visual Studio Code


يمكن استخدام الثغرة الأمنية لاستهداف المطورين الذين لديهم
 Visual Studio Code IDE مثبتًا. عند النقر على رابط ضار صممه مهاجم ، 
يُطلب من الضحايا استنساخ مستودع Git في Visual Studio Code.
 هذه العملية حقيقية وجزء من سير العمل لمعظم المستخدمين. على سبيل المثال ،
 هذه هي الطريقة التي يسمح بها GitLab باستنساخ المشاريع بسهولة:
قائمة منسدلة تسمى "فتح في IDE الخاص بك" في مثيل GitLab:

Clone with SSH:
git@git lab.com:git lab-org/git la
Clone with HTTPS:
https://git lab.com/gitlab-org/g
Open in your IDE:
Visual Studio Code (SSH)
Visual Studio Code (HTTPS)
IntelliJ IDEA (SSH)
IntelliJl 1DEA (HTTPS)

إذا قبل المطور هذه العملية ، يمكن للمهاجمين تنفيذ أوامر عشوائية على كمبيوتر الضحية. 
ومن المثير للاهتمام ، أن Workspace Trust ، وهي ميزة لتقوية IDEs
وتقليل مخاطر تنفيذ الأوامر غير المقصودة ، لا يتم فرضها بصرامة هنا.
 إذا كانت مساحة العمل الحالية موثوقة بآخر نافذة Visual Studio Code
 مع التركيز ، فلن يكون لميزة الأمان هذه التأثير المتوقع. 
لقد كشفت عن هذه النتيجة لـ Microsoft من خلال بوابة الباحث ،
 وتم إصدار التصحيح كجزء من Visual Studio Code 1.67.1 والإصدارات الأحدث.
 قامت Microsoft بنشر معلومات محدودة حول هذا الخطأ كجزء من
نشرة الأمن الخاصة بها وعينت لها CVE-2022-30129. 

في الأقسام أدناه ، سأصف أولاً كيف تم تصميم معالجات عناوين URL في 
Visual Studio Code ، ثم أراجع تنفيذ المعالجات المحجوزة لإجراءات
 Git لتحديد خطأ إدخال الوسيطة. ستصف الأقسام الأخرى كيف يمكن 
استغلالها لاكتساب القدرة على تنفيذ أوامر عشوائية ، بالإضافة إلى التصحيح الذي تنفذه Microsoft. 

معالجات عنوان URL لرمز الاستوديو المرئي


يستخدم Visual Studio Code بشكل شائع كتطبيق سطح مكتب مستقل ،
 وذلك بفضل Electron. لا يزال هذا الاختيار يسمح بمستوى معين من التكامل
 مع نظام تشغيل المستخدم ، على سبيل المثال ، من خلال السماح للتطبيقات بتسجيل
 معالجات بروتوكول URL المخصصة. في حالة Visual Studio Code ، vscode:// 
يتم تسجيله ، vscode-insiders:// وللإصدارات الليلية (تسمى أيضًا Insiders build). 
هذه الميزة تسمى روابط عميقة . 
يسمح IDE للامتدادات الداخلية والخارجية بالاستماع إلى مثل هذه الأحداث و
التعامل معها من خلال تسجيل المعالجات الفرعية. المستمع الرئيسي سيتعامل مع
مثل هذه الأحداث على مستوى نظام التشغيل ويعيد توجيهها إلى الامتداد الصحيح. 

يجب عليهم تنفيذ واجهة بسيطة باستخدام طريقة تسمى handleUri() وإعلانها إلى IDE 
باستخدام window.registerUriHandler():
src / vscode-dts / vscode.d.ts
TypeScript


export interface UriHandler {
    handleUri(uri: Uri): ProviderResult<void>; 
}


إيجاد حقن وسيطة في Git Module


مع وضع هذا التصميم في الاعتبار ، أصبح من الممكن الآن البدء في البحث
 عن معالجات URL في جوهر Visual Studio Code. في ذلك الوقت ،
 كانت ثلاثة متاحة : extensions/github-authentication
والمصادقة extensions/microsoft-authentication
مع خدمات الجهات الخارجية والحصول على رموز الوصول الناتجة ،
 والإضافات / بوابة للسماح للمستخدمين باستنساخ المستودعات البعيدة كما هو موضح أعلاه في GitLab.
من خلال تجربتي السابقة في مراجعة كود أدوات المطور ، أعلم أن الاستدعاءات
 الخارجية لأدوات التحكم في الإصدار غالبًا ما تكون مليئة بأخطاء إدخال الحجج -
 يمكنك التوجه إلى قسم المنشورات ذات الصلة للحصول على بعض الأمثلة.






 دعونا نلقي نظرة على extensions/git تطبيق handlerUri أول!
 extensions/git/src/protocolHandler.ts
TypeScript


export class GitProtocolHandler implements UriHandler {
    // [...]
    handleUri(uri: Uri): void {
     switch (uri.path) {
         case '/clone': this.clone(uri);
     }
    }
    private clone(uri: Uri): void {
     const data = querystring.parse(uri.query);
     // [...]
     commands.executeCommand('git.clone', data.url);
    }



يتم git.clone تنفيذ الأمر في extensions/git/src/commands.ts؛ 
من الممكن أيضًا استدعاؤها يدويًا:

extensions/git/src/commands.ts
TypeScript

@command('git.clone')
async clone(url?: string, parentPath?: string): Promise<void> {
    await this.cloneRepository(url, parentPath); 
}


دعنا نواصل التعمق في الكود لتحديد مكان استدعاء ثنائي Git الخارجي: 

extensions/git/src/commands.ts
TypeScript


async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise<void> {
    // [...]     
    try {
    // [...]
        const repositoryPath = await window.withProgress(
            opts, 
            (progress, token) => this.git.clone(
                url!, { 
                    parentPath: parentPath!, progress, recursive: options.recursive 
                }, 
                token)
            );


******



extensions/git/src/git.ts
TypeScript


async clone(url: string, options: ICloneOptions, cancellationToken?: CancellationToken): Promise<string> {
    let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository';
    let folderName = baseFolderName;
    let folderPath = path.join(options.parentPath, folderName);
    // [...]
    try {
        let command = ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress'];
        if (options.recursive) {
            command.push('--recursive');
        }
        await this.exec(options.parentPath, command, { 

            cancellationToken, 
            env: { 'GIT_HTTP_USER_AGENT': this.userAgent },
            onSpawn,
        });



كما هو موعود ، هناك خطأ في حقن الوسيطة في هذا الكود: يتم التحكم في عنوان 
URL لاستنساخ مستودع Git بشكل كامل ومتسلسل في سطر الأوامر الخارجي.
 إذا بدأ عنوان URL هذا بشرطة ، فسيفهمه Git كخيار بدلاً من وسيطة موضعية. 


استغلال حقن "Injection" وسيطة في عملية Git Clone


نقاط الضعف في حقن الحجج مثيرة جدًا للاهتمام لأنها جميعًا مختلفة و
غالبًا ما تتضمن بعض التفاصيل الدقيقة ؛ هذا ليس استثناء.
 يصف هذا القسم طريقة واحدة لاستغلالها ؛ توجد طرق أخرى وتُترك كتمرين للقارئ. 
يستخدم Git لتنفيذ git-remote-ext"ربط النقل الذكي بأمر خارجي" ،
 ولكن هذه الميزة معطلة الآن افتراضيًا. 

للتذكير ، لدينا نقطتا حقن:

1- url: عنوان URL لمستودع Git البعيد المراد استنساخه 
2- folderPath: المجلد الوجهة المحسوب من عنوان URL لمستودع Git.
هذا مهم جدًا في هذه الحالة لأن خيارنا المحقون يحل محل الحجة الموضعية:
 بدون نقطة الحقن الثانية ، لن يكون لدى Git أي شيء للاستنساخ منه ، ولن يكون الحقن قابلاً للاستغلال.
أخيرًا ، إذا كان هناك أي مساحة في الحمولة ، فسيتم ترميزها بعنوان URL 
قبل استيفائها في سطر الأوامر ؛ سيكون من الأسهل محاولة صنع واحدة بدون فراغات:

extensions/git/src/git.ts
TypeScript


let command = ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress'];


توصلت أنا وفريقي إلى الحمولة التالية:

- vscode://:
 المخطط المخصص المسجل بواسطة Visual Studio Code لنظام التشغيل ؛
- vscode.git/clone?url=: 
مطلوب لتشغيل git.cloneالأمر في Visual Studio Code ؛
-u$({open,-a,calculator}):
 نقوم بحقن الخيار -u، ما يعادل --upload-pack، لتجاوز الأمر الذي سيتم استخدامه للتواصل مع الطرف البعيد ؛  
- :x:
 هذا الجزء مطلوب لخداع Git لاستخدام طبقة النقل والتعرف عليها 
PROTO_LOCALواستدعاء ما سبق ذكره upload-pack.




 


الخلاصة :

عالجت Microsoft هذه المشكلة من خلال تحسين التحقق من صحة عنوان 
URL الخاص بمستودع Git للاستنساخ كجزء من الالتزام c5da533 .
 يتم تحليل عنوان URL باستخدام Uri ، محلل URI داخلي ، للتحقق من
 صحة النظام مقابل قائمة السماح المحددة مسبقًا. الأساس المنطقي وراء هذا التغيير
 هو أن خطأ إدخال الوسيطة لا يمكن أن يحدث إلا إذا تم التحكم في بادئة البيانات بالكامل ، 
وهو ما لن يكون ممكنًا إذا كان جزء المخطط من عنوان URL جزءًا من هذه القائمة:
diff

 
--- a/extensions/git/src/protocolHandler.ts
+++ b/extensions/git/src/protocolHandler.ts
@@ -7,6 +7,8 @@ import { UriHandler, Uri, window, Disposable, commands } from 'vscode';
 import { dispose } from './util';
 import * as querystring from 'querystring';
 +const schemes = new Set(['file', 'git', 'http', 'https', 'ssh']);
+
 export class GitProtocolHandler implements UriHandler {
    private disposables: Disposable[] = [];
@@ -26,9 +28,27 @@ export class GitProtocolHandler implements UriHandler {
        if (!data.url) {
            console.warn('Failed to open URI:', uri);
+           return;
+       }
+
+       if (Array.isArray(data.url) && data.url.length === 0) {
+           console.warn('Failed to open URI:', uri);
+           return;
+       }
+
+       let cloneUri: Uri;
+       try {
+           cloneUri = Uri.parse(Array.isArray(data.url) ? data.url[0] : data.url, true);
+           if (!schemes.has(cloneUri.scheme.toLowerCase())) {
+               throw new Error('Unsupported scheme.');
+           }
+       }
+       catch (ex) {
+           console.warn('Invalid URI:', uri);
+           return;
        }

-       commands.executeCommand('git.clone', data.url);
+       commands.executeCommand('git.clone', cloneUri.toString(true));
    }
    dispose(): void {



لم تكن هذه النتيجة مؤهلة للحصول على مكافأة من برنامج 
Microsoft Bug Bounty ، حيث أن الجزء الأساسي فقط هو جزء من النطاق ؛
 يتم استبعاد الإضافات المضمنة فعليًا حتى لو تم تمكينها افتراضيًا.
 لا يزال هذا التقديم يمنحنا 40 نقطة لبرنامج 
Microsoft Researcher Recognition Program و
حصلنا على لوحة المتصدرين MSRC 2022 Q2. 

من المثير للاهتمام أيضًا ملاحظة أن فريق Visual Studio Code
 بدأ في نشر معلومات حول مشكلات الأمان على GitHub أعلى نشرة
 الأمان المعتادة وملاحظات الإصدار: تمت إضافة أمان التسمية الآن إلى
 المشكلات ، ويتم نشر إرشادات أمان GitHub .

الجدول الزمني

*تاريخ 2022-04-05
الفعل: تم إبلاغ Microsoft بهذه المشكلة على بوابة الباحث الخاصة بها.

*تاريخ 2022-05-06
الفعل: تؤكد Microsoft المشكلة وتبدأ العمل على تصحيح.

*تاريخ 2022-05-10
الفعل : التصحيح جزء من الإصدار 1.67.1.

الملخص
في هذا المنشور ، أوضحت كيف يمكن أن تؤدي ثغرة أمنية في أحد معالجات 
عنوان URL لـ Visual Studio Code إلى تنفيذ أوامر تعسفية على مضيف الضحية.
 يمكن أيضًا تطبيق تقنية الاستغلال التي أظهرتها على أي حقنة حجة أخرى في
 استدعاء استنساخ git. أحث أنا وفريقي جميع المطورين على ترقية IDE الخاص بهم إلى
 أحدث إصدار وأن يظلوا حذرين عند فتح الروابط الخارجية.



جدول المحتويات