الملخص
- أصبح اختراق أداة تحميل Bash من Codecov لعام 2021 اختبارًا للمساءلة عن أسرار CI، لأن التحديث الأمني لـ Codecov ذكر أن طرفًا ثالثًا عدّل أداة تحميل Bash ويحتمل أن يقوم بتصدير متغيرات البيئة ومعلومات Git عن بعد من بيئات CI للعملاء.
- ذكر تقرير ما بعد الحادثة لـ Codecov لاحقًا أن المهاجم استخرج مفتاح HMAC لحساب خدمة Google Cloud Storage من طبقة وسيطة في صورة Docker عامة مستضافة ذاتيًا واستخدم هذا المفتاح لتعديل أداة تحميل Bash المقدمة للمستخدمين النهائيين.
- قضية المساءلة لا تقتصر على أن المستخدمين كان يجب عليهم التحقق من المجاميع الاختبارية. بل إن Codecov كان يتحكم في مسار توزيع أداة التحميل، وعملية بناء صورة Docker العامة، ومراقبة النص البرمجي المستضاف، وإشعار العملاء، وخطة الانتقال بعيدًا عن نمط الثقة في curl-to-shell.
- تحكم العملاء في الأسرار المتاحة لوظائف CI، وطريقة التحميل المستخدمة، وما إذا كان التحقق من المجموع الاختباري مفروضًا، وسرعة تدوير بيانات الاعتماد بعد الإشعار. لكن تلك الضوابط من جانب العملاء لم تمح مسؤولية المزود عن سلامة النص البرمجي.
- تتعامل هذه المقالة مع التحديث الأمني وتقرير ما بعد الحادثة لـ Codecov كمصادر أساسية، واستجابات العملاء للحوادث كأدلة من الدرجة الأولى، ومعايير NIST وCISA وSLSA وSigstore ووثائق CI كمفردات تحكم تقني. لا تدعي الوصول إلى ملفات إنفاذ القانون أو قوائم العملاء الخاصة أو سجلات البنية التحتية الكاملة للمهاجم.
لماذا تنتمي هذه القضية إلى ملف المخاطر والمساءلة
تنتمي Codecov إلى ملف المخاطر والمساءلة لأن اختراق أداة تحميل Bash لعام 2021 حوّل خطوة رفع التغطية الروتينية إلى مسار محتمل لكشف أسرار CI. ذكر التحديث الأمني لـ Codecov بتاريخ 15 أبريل 2021 على الرابط source: about.codecov.io أن Codecov علم في 1 أبريل أن شخصًا ما حصل على وصول غير مصرح به إلى النص البرمجي لأداة تحميل Bash وعدّله دون إذن. قالت الشركة إن الفاعل حصل على الوصول بسبب خطأ في عملية إنشاء صورة Docker لـ Codecov سمح باستخراج بيانات اعتماد مطلوبة لتعديل أداة التحميل.
قالت Codecov أنه بدءًا من 31 يناير 2021، كانت هناك تغييرات غير مصرح بها دورية يمكن أن تصدر معلومات مخزنة في بيئات التكامل المستمر للعملاء إلى خادم طرف ثالث خارج بنية Codecov التحتية.
هذا الحساب العام يجعل القضية أكبر من مجرد نص برمجي مخترق لمزود. تعمل أداة تحميل Bash داخل وظائف CI للعملاء، غالبًا بعد اكتمال الاختبارات وقبل رفع بيانات التغطية. قد تحتوي وظائف CI عناوين URL للمستودعات، وبيانات تعريف البناء، ورموز النشر، وبيانات اعتماد نشر الحزم، وبيانات اعتماد السحابة، ومفاتيح التوقيع، وعناوين URL لقواعد البيانات، وأسرار خطافات الويب، ورموز الوصول الشخصية، ومتغيرات البيئة المستخدمة في أتمتة الاختبار والإصدار. يمكن أن تصبح إضافة ضارة صغيرة إلى أداة التحميل نقطة تجميع لبيانات الاعتماد لأن العملاء يضعون الثقة والأسرار عن قصد في CI.
تقرير ما بعد الحادثة لـ Codecov على الرابط source: about.codecov.io زاد من توضيح قصة التحكم. قال إن الفاعل التهديد استهدف أداة تحميل Bash واستخدمها لتوصيل حمولة ضارة للمستخدمين الذين يستخدمون أداة تحميل Bash، وإجراء Codecov GitHub Action، وCodecov CircleCI Orb، وCodecov Bitrise Step. قال إن المهاجم استخرج مفتاح HMAC لحساب خدمة Google Cloud Storage من طبقة وسيطة في صورة Docker عامة مستضافة ذاتيًا لـ Codecov واستخدم هذا المفتاح لتعديل أداة تحميل Bash في Google Cloud Storage. كما قال إن أحد العملاء اكتشف الحادثة بعد إجراء فحص SHASUM وملاحظة تباين بين التجزئة المبلغ عنها على GitHub والتجزئة المحسوبة لأداة التحميل التي تم تنزيلها.
تضع هذه الحقائق المساءلة في نظام مشترك لكن غير متساوٍ. تحكمت Codecov في أداة التحميل المستضافة، ومسار الكتابة في Google Cloud Storage، وعملية بناء صورة Docker المستضافة ذاتيًا، وتدوير المفاتيح بعد الحادثة، وإشعار العملاء، والانتقال نحو أداة تحميل جديدة. تحكم العملاء في متغيرات CI الموجودة عند تشغيل أداة التحميل، وما إذا كانوا يجلبون النص البرمجي مباشرة، وما إذا تم إجراء التحقق من المجموع الاختباري، ومدى سرعة تدوير الأسرار المكشوفة. تحكم مزودو CI في أجزاء من إخفاء الأسرار وعزل الوظائف والتسجيل. تحمل المستخدمون النهائيون المخاطر إذا مكنت بيانات الاعتماد المكشوفة من الوصول لاحقًا إلى الأنظمة أو الكود.
السؤال العملي هو ما إذا كان لكل طرف أدلة كافية للتصرف في الوقت المناسب.
تتناسب هذه الحادثة مع اقتصاديات أدوات المطورين لأن عرض القيمة لـ Codecov كان تقارير تغطية منخفضة الاحتكاك عبر العديد من أنظمة CI. يُظهر مستودع أداة تحميل Bash المؤرشف لـ Codecov على الرابط source: github.com نمط الراحة مباشرة: يمكن للعملاء جلب وتنفيذ نص برمجي عن بعد، واستخدام نفس أداة التحميل عبر العديد من مزودي CI، والتحقق اختياريًا من SHASUMs. كانت الراحة محرك التبني. ولكن عندما أصبح النص البرمجي الموثوق عن بعد قابلًا للتغيير من مسار يتحكم فيه المهاجم، ظهرت التكلفة الخفية كجرد طارئ لبيانات الاعتماد، والتدوير، ومراجعة المستودع، وإشعار العملاء، والاستجابة للحوادث.
أداة تحميل Bash خلقت انعكاسًا للثقة داخل CI
من السهل التقليل من شأن أدوات تحميل التغطية. تظهر في نهاية وظيفة الاختبار، بعد تشغيل كود التطبيق الرئيسي بالفعل. يمكن أن يجعلها هذا الموضع تبدو أقل خطورة من أدوات البناء أو أوامر النشر أو خطوات نشر الحزم. في الواقع، يمكن لأداة تحميل التغطية رؤية نفس البيئة التي تستدعيها ما لم يعزل خط الأنابيب ذلك عمدًا. إذا كانت الوظيفة تحتوي على بيانات اعتماد سحابية أو رموز API أو وصول إلى المستودع أو أسرار سجل الحزم أو مفاتيح الخدمة، فقد تتمكن عملية أداة التحميل من قراءتها.
وثائق أداة تحميل Bash الخاصة بـ Codecov على الرابط source: docs.codecov.com وتعليمات المستودع المؤرشف تُظهر سبب أهمية ذلك. صُممت أداة التحميل لكشف إعدادات CI وجمع التقارير وإرسال بيانات التغطية. وثق نفس المستودع عملية تحقق باستخدام ملفات SHASUM، لكن تقرير ما بعد الحادثة لـ Codecov اعترف بأن العملية لم تكن موثقة بشكل كامل أو صحيح قبل الحادثة. كما قال التحديث الأمني إن العملاء الذين أجروا مقارنة المجموع الاختباري قبل استخدام أداة تحميل Bash قد لا يتأثرون. هذه حدود كاشفة: التحقق من السلامة كان دفاعًا صالحًا، لكنه لم يكن حتميًا بفعل نموذج التوزيع.
انعكاس الثقة كان بسيطًا. وثق العملاء في نص Codecov البرمجي لأنه كان تبعية في سير عمل يقيس تغطية الاختبار. ثم يعمل النص البرمجي داخل بيئة CI يتحكم فيها العميل ويمكن أن تحتوي على سلطة أكبر بكثير مما تحتاجه Codecov لتلقي تقرير التغطية. في الواقع، أعطى العميل أداة التقارير موقعًا يمكنها من ملاحظة أو تصدير أسرار النشر إذا تم تغيير الأداة. هذا لا يعني أن كل عميل تسربت منه أسرار حاسمة. يعني أن نصف قطر الانفجار يعتمد على تصميم بيئة CI لكل عميل، وليس فقط على حدود خدمة Codecov.
قائمة إشعار Codecov الرسمية ذكرت بيانات الاعتماد والرموز والمفاتيح والخدمات ومخازن البيانات وكود التطبيق ومعلومات Git عن بعد كفئات يمكن أن تتأثر إذا كانت متاحة عند تنفيذ أداة التحميل المعدلة. يجب قراءة هذا البيان بحذر. لم يثبت أن كل عميل فقد كل سر. وصف احتمالية التعرض بناءً على مكان تشغيل النص البرمجي. ثم كان على العملاء تحديد الأسرار الموجودة في وظائفهم الخاصة، وما إذا كانت تلك الأسرار حساسة، وما الأنظمة التي تفتحها، وما إذا كان سوء الاستخدام لاحقًا مرئيًا في السجلات.
توثيق CI الحديث يعزز نموذج المخاطر المشترك هذا. إرشادات تعزيز أمان GitHub Actions على الرابط source: docs.github.com تناقش الأسرار وأذونات الرموز وإجراءات الطرف الثالث ومخاطر حقن النصوص البرمجية. توثيق متغيرات CI/CD لـ GitLab على الرابط source: docs.gitlab.com ووثائق متغيرات البيئة لـ CircleCI على الرابط source: circleci.com تظهر كيف تتعمد أنظمة CI كشف الأسرار للوظائف تحت ظروف محكومة. تلك المستندات ليست نتائج حوادث متعلقة بـ Codecov. إنها تحدد البيئة التي أصبح فيها اختراق Codecov خطيرًا: وظائف CI هي غرف أتمتة مميزة، وليست محطات طرفية محايدة.
توقيت الاكتشاف جعل العملاء يتحملون عدم اليقين
توقيت الاكتشاف هو قضية مساءلة مركزية لأن العملاء لم يتمكنوا من معرفة النطاق فورًا. قالت Codecov إنها علمت بالمشكلة في 1 أبريل 2021 بعد أن أبلغ عميل يقوم بالتحقق من SHASUM عن تباين. الكشف العام في 15 أبريل جاء بعد التحقيق والطب الشرعي والتنسيق. قال التحديث الأمني إن النافذة ذات الصلة بدأت في 31 يناير وأن المستخدمين المتأثرين تم الاتصال بهم عبر البريد الإلكتروني والإشعارات داخل التطبيق. أضاف تحديث 29 أبريل مزيدًا من المعلومات حول متغيرات البيئة التي ربما تم الحصول عليها دون إذن وحول المنظمات والمستودعات المتأثرة.
هناك نقطتا إنصاف يجب جمعهما معًا. أولاً، الاستجابة للحوادث تتطلب تحقيقًا. المزود الذي يكشف قبل أن يفهم الحقائق الأساسية يمكن أن يضلل العملاء ويسبب تصحيحًا خاطئًا. قال تقرير ما بعد الحادثة لـ Codecov إن الشركة نسقت مع وكالات إنفاذ القانون الفيدرالية والأمن السيبراني أثناء التحقيق. ثانيًا، العملاء الذين لديهم أسرار CI مكشوفة لديهم ساعتهم الخاصة. إذا كان بيان اعتماد سحابي أو رمز حزمة أو مفتاح نشر للمستودع أو مفتاح توقيع متاحًا لوظيفة في فبراير، فقد يحتاج العميل إلى تدويره فورًا، ومراجعة سجلات التدقيق، وتقييم التعرض النهائي. كلما طالت مدة عدم اليقين، زادت صعوبة معرفة ما إذا تم استخدام بيانات الاعتماد.
يجب على ملف المساءلة أن يسأل ما الذي عرفه العملاء في 1 أبريل و15 أبريل و29 أبريل. هل عرفوا أي المستودعات استخدمت أدوات التحميل المتأثرة؟ هل عرفوا ما إذا كانوا قد جلبوا أداة التحميل مباشرة خلال النوافذ المخترقة؟ هل عرفوا أي متغيرات بيئة تم الحصول عليها؟ هل عرفوا أي أسرار محددة كانت موجودة في تلك الوظائف؟ هل عرفوا ما إذا تم إجراء التحقق من المجموع الاختباري؟ هل كانت لديهم سجلات كافية لفحص سوء الاستخدام المحتمل؟ هذه الأسئلة تحدد ما إذا كان الإشعار قابلاً للتنفيذ.
صفحة تنبيه CISA لـ Codecov على الرابط source: cisa.gov تعاملت مع إشعار المزود على أنه مهم بما يكفي لتضخيمه. هذا دليل عام مفيد على أن الحادثة كانت مسألة تتعلق بسلسلة التوريد البرمجية وتصحيح العملاء، وليست مجرد حدث داخلي لـ Codecov. إطار تطوير البرمجيات الآمنة من NIST على الرابط source: csrc.nist.gov مفيد هنا أيضًا لأنه يؤطر مكونات البرمجيات الطرف الثالث وبيئات البناء والاستجابة للثغرات كضوابط دورة الحياة. اختراق Codecov يجلس على حدود الثلاثة جميعًا.
قصة الاكتشاف تُظهر أيضًا قيمة وضعف التحقق من جانب العميل. اكتشف عميل التباين لأنه فحص أداة تحميل Bash التي تم تنزيلها مقابل SHASUM المتوقع. هذه إشارة قوية على أن التحقق يعمل. إنه أيضًا تحكم ضعيف إذا كان العملاء الحذرون فقط هم من يقومون به. التصميم الأقوى هو جعل التنفيذ غير الموقّع أو غير القابل للتحقق هو الاستثناء وليس الافتراضي. قال تقرير ما بعد الحادثة لـ Codecov إن أداة التحميل الجديدة سيتم شحنها كملف ثنائي قابل للتنفيذ موقع وقابل للتحقق عبر SHASUM وأن إهمال أداة تحميل Bash كان جزءًا من الإجراء التصحيحي. إعلان أداة التحميل الجديدة على الرابط source: about.codecov.io ينتمي إلى ملف الإصلاح لهذا السبب.
تدوير الأسرار كان عبء العمل الحقيقي على العملاء
بمجرد أن أصبح الاختراق علنيًا، انتقل العبء التشغيلي بسرعة إلى العملاء. نصحت Codecov المستخدمين المتأثرين بتحديد المفاتيح والرموز المكشوفة في بيئات CI، وإبطال بيانات الاعتماد الحساسة، وإنشاء بدائل، وتدقيق استخدام الرموز. يبدو هذا واضحًا حتى يتم تطبيقه على مؤسسة برمجية حقيقية. قد تحتوي وظيفة CI واحدة على رموز سجل الحزم، وبيانات اعتماد مزود السحابة، ومفاتيح النشر، وأسرار مستودع القطع الأثرية، وعناوين URL لقواعد البيانات لاختبارات التكامل، وكلمات مرور حسابات الاختبار، وخطافات ويب Slack أو PagerDuty، وكلمات مرور سجل Docker، وبيانات اعتماد حالة Terraform، ومواد التوقيع، أو رموز الوصول الشخصية.
قد يتم إعادة استخدام تلك الأسرار عبر المستودعات أو تكون موروثة من إعدادات CI على مستوى المؤسسة.
التحدي من جانب العميل لم يكن مجرد التدوير. كان رسم الخرائط. أي المستودعات استخدمت أداة التحميل المتأثرة؟ أي الوظائف عملت خلال النوافذ المتأثرة؟ أي متغيرات البيئة كانت موجودة في تلك الوظائف؟ هل تم إخفاء الأسرار في السجلات ولكنها لا تزال قابلة للقراءة من قبل العملية؟ أي حسابات سحابية، وسجلات حزم، ومستضيفي كود، وخدمات داخلية قبلت تلك البيانات؟ أي أنظمة لديها سجلات تدقيق؟ كم من الوقت تم الاحتفاظ بالسجلات؟ هل يمكن للمؤسسة إثبات عدم سوء الاستخدام، أم فقط التدوير الوقائي؟ لذلك تم قياس تكلفة الحادثة من حيث عمل الاستجابة للحوادث بقدر ما تم قياسها من حيث سوء الاستخدام المؤكد.
استجابات العملاء من الدرجة الأولى تظهر لماذا هذا مهم. إشعار HashiCorp الأمني العام على الرابط source: discuss.hashicorp.com وصف تعرض مفتاح GPG خاص يستخدم لتوقيع الإصدارات وعملية الإبطال والاستبدال. استجابة Twilio على الرابط source: twilio.com وصفت تحقيقها وتقييم تأثير العملاء. استجابة Rapid7 على الرابط source: rapid7.com وصفت مراجعتها وتصحيحها. تقرير حادثة Mercari على الرابط source: about.mercari.com وصف تعرض بيانات العملاء والموظفين المرتبط بحادثة Codecov. هذه ليست دليلاً على أن كل عميل Codecov كان له نفس النتيجة. إنها أدلة من المصب على أن تصحيح العملاء كان حقيقيًا ومتنوعًا وذا عواقب.
مثال HashiCorp مفيد بشكل خاص لأن مفاتيح التوقيع ليست رموز API عادية. مفتاح التوقيع يمكن أن يؤثر على صحة البرمجيات. استبداله يتطلب الإبطال، وتوزيع الثقة الجديد، والتواصل مع العملاء، والوقت. هذا لا يعني أن Codecov اخترقت كل قطعة أثرية موقعة بشكل مباشر. يعني أن كشف أسرار CI يمكن أن يصل إلى سلسلة التوريد البرمجية إذا كانت المواد المكشوفة تتضمن مفاتيح تستخدم لتوثيق أو توزيع البرمجيات. نصف قطر الانفجار يعتمد على نوع السر واستخدامه وعمره وأدلة الإبطال.
مثال Mercari يوضح حدًا آخر. حادثة Codecov كانت اختراقًا لأداة مزود، لكن تعرض بيانات العميل يمكن أن يصبح مرئيًا في بيئة العميل الخاصة اعتمادًا على الأسرار والأنظمة المتاحة لوظائف CI المتأثرة. لهذا السبب لا يمكن فصل مساءلة المزود ومساءلة العميل في صناديق منفصلة. كان على Codecov إصلاح سلامة أداة التحميل وإخبار العملاء بما حدث. كان على العملاء تحديد الأسرار الموجودة وما يمكن أن تصل إليه تلك الأسرار.
سلامة التوزيع كانت مطالبة الإصلاح المركزية
مطالبة الإصلاح المركزية بعد حادثة Codecov كانت سلامة التوزيع. نمط أداة تحميل Bash شجع العملاء على جلب كود قابل للتنفيذ في وقت تشغيل الوظيفة. هذا النمط جعل التحديثات سهلة ودعم اللغة واسعًا، ولكنه جعل أيضًا النص البرمجي المستضاف هدفًا عالي القيمة. إذا تمكن المهاجم من تعديل النص البرمجي في التخزين، فإن كل جلب غير محقق من المصب يمكن أن يرث التغيير الضار. لذلك كان على المزود أن يظهر أن حقوق التعديل والتوقيع والمجاميع الاختبارية والمراقبة وبناء الصور وإجراءات الإصدار قد تغيرت.
تقرير ما بعد الحادثة لـ Codecov سرد العديد من الإجراءات التصحيحية: إبطال المفتاح المسروق، تدقيق وتدوير مفاتيح الإنتاج، تحديث صور Docker العامة لاستخدام بنيات متعددة المراحل أو مضغوطة، إطلاق أداة تحميل جديدة، مراقبة أصول Google Cloud Storage ذات الصلة، تحسين التوثيق للتحقق من التوقيع وSHASUM، تغيير سياسة إنشاء المفاتيح وتدويرها، تعزيز الاستجابة للحوادث، وتوظيف وظيفة أمنية مخصصة. كل إجراء عالج جزءًا مختلفًا من السلسلة. إصلاح صورة Docker عالج تسرب الأسرار عبر طبقات الصورة. تدوير المفاتيح عالج مسار بيانات الاعتماد المباشر. المراقبة عالجت التعديل غير المصرح به في المستقبل. أداة التحميل الجديدة عالجت تصميم التوزيع والتحقق.
طبقات صورة Docker هي نقطة أدلة مهمة. قال Codecov إن المهاجم استخرج مفتاح HMAC من طبقة وسيطة في صورة Docker عامة مستضافة ذاتيًا. وثائق Docker الخاصة بالبنيات متعددة المراحل على الرابط source: docs.docker.com تشرح لماذا يجب إبقاء القطع الأثرية للبناء والمواد الوسيطة خارج الصور النهائية. الإجراء التصحيحي في تقرير ما بعد الحادثة لـ Codecov لاستخدام البنيات المضغوطة أو متعددة المراحل كان مرتبطًا مباشرة بفئة السبب الجذري. السر في طبقة الصورة ليس محميًا لمجرد أن الحاوية النهائية تبدو نظيفة.
مفردات سلسلة التوريد البرمجية الأوسع تساعد أيضًا. إطار SLSA على الرابط source: slsa.dev وSigstore على الرابط source: sigstore.dev يعالجا كلاهما السلامة والمصدر والتوقيع والتحقق من القطع الأثرية البرمجية. إنها ليست اختبارات امتثال بأثر رجعي لأداة تحميل Codecov لعام 2021. إنها تحدد لماذا النص البرمجي المستضاف القابل للتغيير هو نموذج توزيع أضعف من قطعة أثرية موقعة ومرقمة وقابلة للتحقق مع مصدر. OpenSSF Scorecard على الرابط source: scorecard.dev يؤطر بالمثل النظافة التبعية والمستودع كضوابط سلسلة توريد قابلة للقياس. النقطة المهمة ليست أن إطارًا واحدًا كان سيمنع كل جزء من الحادثة.
النقطة هي أن سلامة القطع الأثرية يجب أن تصمم بحيث لا يُتوقع من العملاء اكتشاف العبث يدويًا.
وثائق أداة تحميل Codecov الحالية على الرابط source: docs.codecov.com ومستودع أداة التحميل على الرابط source: github.com تظهر اتجاه الهجرة بعيدًا عن النمط القديم القائم على Bash فقط. مستودع إجراء GitHub Codecov على الرابط source: github.com لا يزال ذا صلة لأن العديد من المستخدمين استهلكوا Codecov من خلال تكاملات المنصة بدلاً من استدعاء Bash المباشر. أظهرت الحادثة أن الأغلفة و orbs والخطوات يمكن أن ترث حد الثقة لأداة تحميل أساسية مشتركة. قد يعتقد العملاء أنهم يستخدمون تكاملًا أصليًا لـ CI، لكن المخاطرة قد تظل تتدفق عبر نفس النص البرمجي عن بعد أو الثنائي.
مزودو CI والعملاء ما زالوا بحاجة إلى تقليل نصف قطر الانفجار
إصلاح المزود كان ضروريًا، لكن تقليل نصف قطر الانفجار من جانب العميل بقي أساسيًا. يجب ألا تكشف بيئة CI أسرارًا لا تحتاجها الوظيفة. خطوة رفع التغطية تحتاج عمومًا إلى سلطة كافية لقراءة ملفات التغطية والمصادقة على Codecov. لا يجب أن تحتاج إلى بيانات اعتماد نشر سحابية واسعة، أو وصول إلى قاعدة بيانات الإنتاج، أو سلطة نشر حزم، أو رموز شخصية طويلة العمر ما لم تكن نفس الوظيفة تجمع مسؤوليات غير ذات صلة. الأقل امتيازًا في CI ليس نظريًا. يحدد ما إذا كان إجراء طرف ثالث مخترق أو نص برمجي يرى رمز تحميل غير ضار أم بيان اعتماد على مستوى المؤسسة.
GitHub Actions وGitLab CI وCircleCI وBuildkite وJenkins وأنظمة CI الأخرى تعطي المؤسسات طرقًا لتحديد نطاق المتغيرات، وفصل الوظائف، وإخفاء الأسرار، وتقييد الوصول إلى الفروع، وطلب بيئات محمية، وتحديد أذونات الرموز. لكن هذه الضوابط مفيدة فقط إذا كان تصميم خط الأنابيب يستخدمها. الوظيفة المتجانسة التي تشغل الاختبارات، وتبني القطع الأثرية، وتنشر البنية التحتية، وتوقع الإصدارات، وتنشر الحزم، وترفع التغطية تخلق تعرضًا للوضع المشترك. إذا كانت خطوة التغطية النهائية يمكنها قراءة كل متغير بيئة استخدمته الخطوات السابقة، فإن نصف قطر الانفجار يُحدد بالراحة وليس بالحاجة.
لذلك ينتمي حدث Codecov إلى أتمتة الأمان بالإضافة إلى اقتصاديات أدوات المطورين. الأتمتة من المفترض أن تقلل المخاطر اليدوية. لكن الأتمتة يمكنها أيضًا إخفاء افتراضات الثقة. قد يكون ملف YAML قد تم نسخه منذ سنوات. قد يعمل أمر أداة التحميل في عشرات المستودعات. قد يتم حقن سر على مستوى المؤسسة في كل وظيفة لأنه كان أسهل من تحديد نطاقه لكل مشروع. قد يكسر الرمز المدرّع خطوط الأنابيب إذا كانت الملكية غير واضحة. أجبرت الحادثة الفرق على تدقيق الأتمتة التي أصبحت بنية تحتية خلفية.
يجب أن تتضمن أدلة العملاء جرد أسرار CI، ومراجعة أذونات الوظائف، وسجل تدوير الرموز، ومراجعة سجل التدقيق، وخريطة التبعية لإجراءات أو نصوص الطرف الثالث. إذا كانت المؤسسة لا تستطيع الإجابة عن أي المستودعات استخدمت أداة تحميل معينة خلال نافذة محددة، لا يمكنها تحديد نطاق التعرض بثقة. إذا كانت لا تستطيع الإجابة عن الأسرار الموجودة، لا يمكنها التدوير بذكاء. إذا كانت لا تستطيع معرفة ما إذا تم استخدام رمز بعد التعرض، لا يمكنها فصل سوء الاستخدام المؤكد عن التدوير الوقائي.
لهذا اختلفت إشعارات العملاء العامة. بعض المنظمات أبلغت عن عدم وجود دليل على وصول غير مصرح به بعد التحقيق. أخرى دارت المفاتيح أو كشفت عن تعرض أكثر واقعية. هذا التباين ليس متناقضًا. إنه يعكس حقيقة أن أداة تحميل Codecov المخترقة خلقت آلية استخراج محتملة، بينما النتيجة النهائية تعتمد على كل بيئة CI. يجب على السجل المساءل أن يحتفظ بالتعرض المحتمل، والوصول المؤكد للأسرار، وسوء الاستخدام المؤكد، وتأثير بيانات العميل في فئات منفصلة.
حدود الأدلة وعدم المبالغة في الادعاء
الأدلة العامة تدعم استنتاجًا قويًا ولكن ليس ادعاءات غير محدودة. تدعم أن أداة تحميل Bash لـ Codecov تم تعديلها دون إذن، وأن التعديل يمكن أن يصدر متغيرات البيئة ومعلومات Git عن بعد من بيئات CI، وأن النافذة ذات الصلة بدأت في 31 يناير وانتهت بالتصحيح في 1 أبريل 2021، وأن تباين المجموع الاختباري من عميل ساعد في اكتشاف المشكلة، وأن طبقة صورة Docker عامة كشفت عن بيانات اعتماد استخدمت لتعديل أداة التحميل، وأن Codecov أوصت بتدوير بيانات الاعتماد للمستخدمين المتأثرين. تدعم أن بعض العملاء كشفوا علنًا عن تصحيحهم أو تعرضهم.
الأدلة العامة لا تدعم الادعاء بأن كل عميل Codecov سرب أسرارًا حساسة، أو أن كل سر مكشوف استخدم، أو أن كل حادثة لاحقة سببها Codecov، أو أن Codecov عرفت التأثير الكامل قبل الكشف. لا تكشف عن قائمة العملاء المتأثرين الكاملة، أو سجلات البنية التحتية الكاملة للمهاجم، أو جميع نتائج إنفاذ القانون، أو جميع تقارير الطب الشرعي، أو كل متغير بيئة للعميل تم الحصول عليه. يجب على ملف المساءلة الجاد تسمية هذه المجهولات بدلاً من ملئها بالشك.
الفرق بين التعرض المحتمل وسوء الاستخدام المؤكد مهم للعملاء والمستخدمين النهائيين. تحدث التحديث الأمني لـ Codecov عن بيانات الاعتماد والرموز والمفاتيح والخدمات ومخازن البيانات وكود التطبيق ومعلومات Git عن بعد التي يمكن أن تتأثر إذا كانت متاحة لأداة التحميل. هذا الاحتمال كان مهمًا بما يكفي لتبرير توجيه التدوير الواسع. لكن الاحتمال ليس نفس دليل الوصول اللاحق. إشعارات حوادث العملاء ضرورية لأن كل عميل كان عليه تطبيق مسار التعرض العام على بيئته الخاصة.
توقيت الكشف هو حد آخر. كشفت Codecov علنًا في 15 أبريل بعد اكتشاف الحدث في 1 أبريل. أوضحت الشركة أنها كانت تحقق مع خبراء الطب الشرعي وتنسق مع السلطات. لا يزال بإمكان العملاء السؤال عما إذا كان التحذير المبكر المستهدف ممكنًا، وما إذا كان ينبغي إبلاغ العملاء ذوي المخاطر العالية في وقت أقرب، وما إذا كانت المعلومات الإضافية في 29 أبريل وصلت بالسرعة الكافية. هذه أسئلة مساءلة مشروعة. إنها ليست دليلًا على سوء النية دون مزيد من الأدلة.
كما لا يجب أن تعامل المقالة التحقق من المجموع الاختباري كنقل كامل للمسؤولية. وثقت Codecov التحقق من SHASUM واستخدم عميل ذلك التحكم لاكتشاف المشكلة. هذه الحقيقة لا تعني أن كل عميل كان مهملاً إذا لم ينفذ الإجراء الاختياري. إذا كان نمط الاستخدام الشائع للمنتج هو جلب نص برمجي عن بعد مباشر، كان على المزود أن يتحمل المخاطرة التي سيسلكها العديد من العملاء في المسار السهل. كلما كان التكامل أكثر سلاسة، زادت مسؤولية المزود في بناء فحوصات السلامة في المسار الافتراضي.
اختبار المساءلة الدائم هو دليل الثقة التي تم إصلاحها
اختبار المساءلة الدائم هو ما إذا كانت Codecov وعملاؤها قد حولوا الحادثة إلى دليل على الثقة التي تم إصلاحها. بالنسبة لـ Codecov، الدليل يعني إبطال المفتاح المسروق، وتدوير بيانات الاعتماد الداخلية، وإزالة أسرار طبقة الصورة المكشوفة، وتغيير عمليات بناء صورة Docker، ومراقبة تخزين النص البرمجي المستضاف، وتوثيق التحقق، وشحن أداة تحميل بديلة موقعة وقابلة للتحقق، وتحسين الاستجابة للحوادث. بالنسبة للعملاء، الدليل يعني تحديد المستودعات المتأثرة، وتعداد أسرار CI، وتدوير البيانات المكشوفة، ومراجعة سجلات المصب، وتضييق أذونات الوظائف، واعتماد التحقق من أدوات الطرف الثالث.
سؤال الإصلاح الرئيسي هو افتراض التوزيع. إذا كان العملاء لا يزالون يجلبون وينفذون كودًا قابلًا للتغيير دون تحقق مدمج، فإن نفس فئة المخاطر تبقى. إذا كانت أدوات التحميل موقعة ومرقمة ومثبتة وخاضعة للمجموع الاختباري والمراقبة، يتم تقليل المخاطرة. إذا كانت وظائف CI تعزل رفع التغطية عن سلطة النشر، فإن اختراق أداة تحميل في المستقبل سيكون لديه أقل للسرقة. إذا أصدر مديرو الأسرار بيانات اعتماد قصيرة العمر بدلاً من الرموز طويلة العمر، يصبح التدوير الطارئ أسهل. إذا تم الاحتفاظ بسجلات التدقيق لفترة كافية، يمكن للعملاء التمييز بين الاحتياط وسوء الاستخدام المؤكد.
يجب أن تتعلم فرق المشتريات والحوكمة من هذه القضية أيضًا. أداة المطور التي تعمل في CI ليست إضافة مراقبة غير ضارة. إنها تنفيذ كود داخل بيئة أتمتة قد تحتوي على أسرار عالية القيمة. يجب أن تسأل مراجعات البائعين كيف يتم توزيع أدوات التحميل والإجراءات، وما إذا كانت القطع الأثرية موقعة، وكيف يتم اكتشاف الاختراق، وكيف يتم إشعار العملاء، وما هي القياسات التي يمكن للبائع تقديمها لتحديد المستودعات المتأثرة، وكيف يتجنب البائع تخزين أو كشف مفاتيح التوقيع في القطع الأثرية العامة للبناء.
الحادثة أيضًا غيرت معنى "أتمتة الأمان". الأتمتة ليست آمنة لأنها آلية. إنها آمنة عندما تكون للأتمتة سلطة محدودة، ومدخلات قابلة للتحقق، وقطع أثرية قابلة للتكرار، وسجلات قابلة للتدقيق، وإبطال سريع. اختراق أداة تحميل Bash لـ Codecov أظهر أن خطوة أتمتة صغيرة يمكن أن تصبح حد ثقة كبير إذا كانت تعمل أينما تعيش الأسرار.
الدرس النهائي عملي. بيانات التغطية مهمة، لكن رفع التغطية يجب ألا يشارك الغرفة مع كل بيان اعتماد تملكه الشركة. يجب على مزود القياس عن بعد للمطورين إثبات سلامة الكود الذي يطلب من العملاء تشغيله. يجب على العملاء تصميم CI بحيث ترى أدوات الطرف الثالث فقط ما تحتاجه. عندما يعتمد أي من الجانبين على الراحة دون دليل، تصل الفاتورة كتدوير طارئ للأسرار، وإشعار العملاء، وعدم يقين في سلسلة التوريد. Codecov جعلت تلك الفاتورة مرئية.
أداة التحميل كانت صغيرة، لكن سياق وقت التشغيل كان كبيرًا
أحد أسباب بقاء حادثة Codecov مهمة هو أن الكائن المخترق كان صغيرًا من الناحية التشغيلية. لم يكن مستضيف كود مصدر كامل أو وحدة تحكم سحابية أو مزود هوية أو سجل حزم. كان أداة تحميل تغطية. لكن سياق وقت تشغيل أداة التحميل يمكن أن يكون كبيرًا لأن وظائف CI تجمع السلطة من العديد من الأنظمة في وقت واحد. وظيفة اختبار يمكنها استنساخ مستودع خاص، وتنزيل التبعيات، والوصول إلى مرايا الحزم الداخلية، وفك تشفير بيانات اختبار، وبدء خدمات سحابية، ونشر التقارير، والمصادقة على منصة التغطية، وتشغيل خطوات النشر لاحقًا. إذا كانت نفس متغيرات البيئة مرئية عبر تلك الوظيفة بأكملها، فإن نص برمجي للتقرير النهائي يرث وصولًا تم إنشاؤه لأغراض أخرى.
لهذا السبب يجب تنفيذ الأقل امتيازًا في CI على مستوى الوظيفة والخطوة، وليس فقط على مستوى المؤسسة. السر المناسب للنشر يجب ألا يتم حقنه في وظيفة تغطية فقط. رمز نشر الحزم يجب ألا يكون متاحًا أثناء خطوة اختبار الوحدة التي ترفع التغطية. بيان اعتماد سحابي يستخدم لاختبارات التكامل يجب أن يكون قصير العمر ومحدد النطاق لموارد الاختبار. رموز المستودع يجب أن يكون لها أذونات ضئيلة. أسرار الفروع المحمية يجب ألا تتعرض لسياقات طلبات السحب غير الموثوقة. اختراق Codecov لم يخترع تلك القواعد، لكنه قدم سببًا ملموسًا لتنفيذها.
الحادثة تظهر أيضًا لماذا إخفاء الأسرار ليس كافيًا. منصات CI غالبًا ما تخفي الأسرار في السجلات، وهو مفيد، لكن الإخفاء لا يمنع العملية من قراءة متغير البيئة وإرساله إلى مكان آخر. الإخفاء يحمي القراء البشر من السجلات. لا يحول السر عالي السلطة إلى سر منخفض السلطة. إذا كان نص برمجي لطرف ثالث يعمل في نفس سياق العملية مثل السر، فإن التحكم قد انتقل بالفعل من السرية في السجلات إلى الثقة في الكود. هذا افتراض أقوى بكثير.
تصميم أقوى يفصل رفع التغطية إلى مرحلة مقيدة. المرحلة تتلقى فقط ملفات التغطية والرمز المطلوب للمصادقة على خدمة التغطية. تشغل إصدار أداة تحميل مثبت أو ثنائي موقع ومتحقق منه. ليس لديها بيانات اعتماد نشر، ولا مفاتيح سحابية إنتاج، ولا رموز نشر حزم، ولا رموز وصول شخصية طويلة العمر، ولا وصول إلى مخرجات الوظائف غير ذات الصلة. إذا تم اختراق أداة التحميل لاحقًا، يرى المهاجم بيئة ضيقة. تصبح الحادثة مشكلة سلامة مزود بدلاً من حدث تدوير أسرار على مستوى المؤسسة.
هذا التصميم يساعد أيضًا في التحقيق. عندما يكون لأداة طرف ثالث مخترقة بيئة ضيقة، يمكن للمستجيبين الإجابة على أسئلة التعرض بسرعة. يعرفون أي رمز كان موجودًا، وأي نظام وصل إليه، وما إذا كان قد تم تدويره، وما السجلات التي يجب فحصها. عندما تحتوي الوظيفة على العديد من الأسرار الموروثة، يجب على المستجيبين إعادة بناء رسم بياني واسع تحت ضغط الوقت. جاءت التكلفة التشغيلية لحادثة Codecov جزئيًا من ذلك عدم اليقين. كان على العملاء اكتشاف ما جعلته وظائف CI الخاصة بهم مرئيًا.
التحقق يجب أن يكون افتراضيًا وقابلًا للملاحظة ومملًا
سجل Codecov يوضح أيضًا مبدأ أوسع: التحقق من البرمجيات يجب أن يكون افتراضيًا وقابلًا للملاحظة ومملًا. يجب ألا يعتمد على عميل حذر واحد يلاحظ تباينًا في التجزئة. العميل الذي اكتشف التباين أدى خدمة عامة مهمة، لكن قناة التوزيع الناضجة يجب أن تجعل العبث مرئيًا لكل مستهلك أو توقف التنفيذ تلقائيًا. هذا يعني إصدارات مثبتة، وقطع أثرية موقعة، ونشر مجموع اختباري مستقل، وبنيات قابلة للتكرار أو التدقيق حيثما أمكن، ومراقبة لتغييرات الكائن غير المتوقعة، وتوثيق واضح يمكن للفرق العادية اتباعه دون أن يصبحوا متخصصين في سلسلة التوريد.
هناك توازن عملي. أدوات المطورين تنجح لأنها سهلة التبني. إذا كان التحقق صعبًا جدًا، ستتخطاه الفرق. إذا كان التحقق اختياريًا ومدفونًا، فقط الفرق الأكثر وعيًا بالأمان ستستخدمه. لذلك على المزود تصميم التكامل الافتراضي بحيث يكون المسار الآمن هو المسار الطبيعي. يجب أن يثبت إجراء GitHub Action الإصدارات والأذونات بوضوح. يجب أن يكون أداة التحميل الثنائية موقعة ومتحققًا منها عبر تعليمات التثبيت. يجب ألا يغلف CI orb أو step نصًا برمجيًا عن بعد قابلًا للتغيير دون جعل تلك التبعية مرئية. يجب أن يشرح التوثيق أنماط الفشل، وليس فقط أوامر المسار السعيد.
قابلية الملاحظة مهمة على جانب المزود أيضًا. قال تقرير ما بعد الحادثة لـ Codecov إنه أضاف مراقبة لأصول Google Cloud Storage ذات الصلة. فئة التحكم هذه أساسية. يجب أن ينتج سلة تخزين النص البرمجي أو الثنائي المستضاف تنبيهات عندما يتغير المحتوى بشكل غير متوقع، أو عندما تستخدم المفاتيح من سياقات غير عادية، أو عندما تتغير بيانات تعريف الكائن، أو عندما تتباعد مسارات الإصدار عن الأتمتة المتوقعة. التوقيع يحمي العملاء في وقت التنفيذ. المراقبة تحمي المزود في وقت التوزيع. كلاهما مطلوب.
أخيرًا، يجب أن تبقى أدلة التحقق بعد الحادثة. بعد الاختراق، يحتاج العملاء إلى معرفة إصدارات القطع الأثرية التي كانت موجودة، ومتى تغيرت، وما التوقيعات الصالحة، وأي مسارات التكامل جلبت أي قطعة أثرية، وأي المستودعات عملت خلال الفترة المتأثرة. المزود الذي لا يستطيع الإجابة على هذه الأسئلة يترك العملاء لاستنتاج التعرض من سجلات قد تكون غير كاملة. أفضل إصلاح بعد Codecov ليس فقط أداة تحميل أكثر أمانًا. إنه سجل أدلة التوزيع الذي يسمح للعملاء بتحديد نطاق الحوادث المستقبلية بسرعة.
هذا السجل هو الجسر بين مسؤولية المزود وإجراء العميل. يمكن لـ Codecov جعل سلامة أداة التحميل قابلة للتحقق. يمكن للعملاء تضييق أسرار CI وتثبيت التبعيات. يمكن لمنصات CI دعم حدود الأذونات ونطاق الأسرار وسجلات التدقيق. لا يكفي أي من هذه الضوابط بمفرده. معًا، يحولون خطوة رفع التغطية من افتراض ثقة مخفي إلى حد أتمتة محكوم.
يجب على المشتريات معاملة أدوات CI ككود مميز
درس المشتريات مباشر: أي أداة تنفذ في CI يجب مراجعتها ككود مميز، حتى لو كانت وظيفة العمل تبدو رصدية. تقارير التغطية، والتحليل الثابت، وفحص التبعيات، ورفع القطع الأثرية، وإنشاء ملاحظات الإصدار، وتوثيق النشر، وإشعارات النشر يمكنها جميعًا العمل في بيئات تحمل أسرارًا. استبيان البائع الذي يسأل فقط عما إذا كانت الخدمة تخزن بيانات العميل يفوت السؤال الأكثر أهمية: ما الكود الذي يطلب البائع من العميل تشغيله، ومن أين يأتي ذلك الكود، وكيف يتم التحقق منه، وما السلطة التي يمكنه ملاحظتها أثناء التنفيذ؟
المراجعة المفيدة ستسأل عما إذا كان البائع ينشر إصدارات موقعة، وما إذا كان العملاء يمكنهم تثبيت إصدارات غير قابلة للتغيير، وما إذا كانت النصوص المستضافة مراقبة للتغييرات غير المتوقعة، وما إذا كانت مفاتيح التوزيع معزولة عن القطع الأثرية العامة للبناء، وما إذا كانت إشعارات الحوادث يمكنها تحديد مسارات التكامل المتأثرة، وما إذا كان البائع يمكنه تقديم قياسات كافية للعملاء لتحديد نطاق التعرض. ستسأل أيضًا عما إذا كان العميل قد فصل مراحل CI بحيث تتلقى أداة البائع فقط الأذونات التي تحتاجها. الإجابة تعاقدية جزئيًا، ومعمارية جزئيًا، وتشغيلية جزئيًا.
يجب أن تعامل المراجعة أيضًا دعم الحوادث كجزء من المنتج. عندما يكشف بائع متكامل مع CI عن اختراق، يحتاج العملاء إلى أكثر من منشور مدونة عام. يحتاجون إلى تجزئات القطع الأثرية، ونوافذ الوقت المتأثرة، وأسماء التكاملات، وطريقة الكشف، وترتيب التدوير الموصى به، والافتراضات الخاطئة المعروفة، وطريقة لسؤال ما إذا كانت مستودعاتهم أو رموزهم قد لوحظت. قد لا يتمكن البائع من الكشف عن كل تفاصيل الطب الشرعي، خاصة أثناء التحقيقات النشطة من قبل إنفاذ القانون أو العملاء، لكن يمكنه إعداد حزمة استجابة تسمح للعملاء بالتصرف بسرعة. أظهرت حادثة Codecov أن العبء التشغيلي لأداة مطور مخترقة يهبط داخل مئات أو آلاف خطوط أنابيب العملاء، وليس فقط داخل فريق أمان البائع.
يجب اختبار حزمة الدعم هذه قبل وقوع حادثة. يجب أن يعرف المزود أي الأنظمة المواجهة للعملاء يمكنها إرسال إشعارات عاجلة، وأي صفحات التوثيق ستستضيف توجيهات التدوير، وأي قوائم دعم ستفرز البيئات عالية المخاطر، وأي السجلات يمكن أن تساعد العملاء في تحديد ما إذا كان التكامل قد عمل خلال النافذة المتأثرة. بدون هذا الإعداد، يصبح الكشف وضع فشل ثانوي: قد يكتشف المزود الحادثة التقنية، لكن العملاء ما زالوا يفقدون الوقت في إعادة بناء خريطة التعرض العملية. لذلك لا تشمل المساءلة فقط منع العبث بأداة التحميل ولكن أيضًا جعل الساعة الأولى من استجابة العميل قابلة للاستخدام.
هذه القضية ليست إذن مجرد ملاحظة تاريخية حول نص Bash واحد مخترق. إنها قالب للحكم على أدوات المطورين التي تقع داخل الأتمتة. السؤال الآمن لم يعد "هل نثق في هذا البائع؟" بشكل تجريدي. السؤال الآمن هو "ما الذي يمكن أن يقرأه هذا الكود الذي يتحكم فيه البائع إذا تغير غدًا، وما الأدلة التي ستظهر لنا بسرعة؟" حادثة Codecov جعلت هذا السؤال مرئيًا لكل فريق سمح لنص برمجي مريح بالعمل بجانب أسرار على مستوى الإنتاج.

